﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using FANUC.DTO;

namespace FANUC.BLL
{
    public class TraceService : IDisposable
    {
        private FANUCDB db = new FANUCDB();

        public UnitListTraceDtoOut GetUnitListTraceRecords(UnitListTraceDtoIn input)
        {
            List<Part_Unit> query = new List<Part_Unit>();
            if (input == null)
            {
                return null;
            }
            if (input.QualityGradeGood == null && input.QualityGradeNG == null && input.QualityGradeOK == null)
            {
                query = db.Part_Unit.Where(a =>
            (String.IsNullOrEmpty(input.BatchNo) == true ? true : a.Batch == input.BatchNo) &&
            (input.EndTime == null ? true : a.End_Time <= input.EndTime) &&
            (input.StartTime == null ? true : a.End_Time >= input.StartTime) &&
            (String.IsNullOrEmpty(input.PartName) == true ? true : a.Part_Name == input.PartName) &&
            (String.IsNullOrEmpty(input.PartSerial) == true ? true : a.Part_Serial == input.PartSerial) &&
               (input.StationNo == null ? true : a.Station_No == input.StationNo) &&
            (String.IsNullOrEmpty(input.RobotNo) == true ? true : a.Robot.YH_No == input.RobotNo)
            ).OrderBy(a => a.ID).ToList();
            }
            else
            {
                query = db.Part_Unit.Where(a =>
                (String.IsNullOrEmpty(input.BatchNo) == true ? true : a.Batch == input.BatchNo) &&
                (input.EndTime == null ? true : a.End_Time <= input.EndTime) &&
                (input.StartTime == null ? true : a.End_Time >= input.StartTime) &&
                (String.IsNullOrEmpty(input.PartName) == true ? true : a.Part_Name == input.PartName) &&
                (String.IsNullOrEmpty(input.PartSerial) == true ? true : a.Part_Serial == input.PartSerial) &&
                   (input.StationNo == null ? true : a.Station_No == input.StationNo) &&
                (String.IsNullOrEmpty(input.RobotNo) == true ? true : a.Robot.YH_No == input.RobotNo) &&
                     (
                   a.Quality_Grade == input.QualityGradeGood ||
                   a.Quality_Grade == input.QualityGradeOK ||
                   a.Quality_Grade == input.QualityGradeNG
                   )
                ).OrderBy(a => a.ID).ToList();
            }
            //.OrderBy(a => a.ID).Skip(input.PageIndex).Take(input.PageSize).ToList();

            AutoMapper.Mapper.Initialize(cfg => cfg.CreateMap<Part_Unit, UnitListTraceRowDto>().ForMember(dest => dest.RobotNo, src => src.MapFrom(s => s.Robot.YH_No))
            .ForMember(dest => dest.BatchNo, src => src.MapFrom(s => s.Batch))
             .ForMember(dest => dest.StartTime, src => src.MapFrom(s => s.Start_Time))
            .ForMember(dest => dest.EndTime, src => src.MapFrom(s => s.End_Time))
            .ForMember(dest => dest.InsertTime, src => src.MapFrom(s => s.Insert_Time))
            .ForMember(dest => dest.PartName, src => src.MapFrom(s => s.Part_Name))
            .ForMember(dest => dest.PartSerial, src => src.MapFrom(s => s.Part_Serial))
              .ForMember(dest => dest.QualityGrade, src => src.MapFrom(s => s.Quality_Grade))
              .ForMember(dest => dest.StationNo, src => src.MapFrom(s => s.Station_No))
              );
            UnitListTraceDtoOut data = new UnitListTraceDtoOut();
            data.TableData = AutoMapper.Mapper.Map<List<UnitListTraceRowDto>>(query);
            data.PageIndex = input.PageIndex + 1;
            data.PageSize = input.PageSize;
            data.TotalPages = input.PageSize == 0 ? 0 : db.Part_Unit.Count() / input.PageSize;
            foreach (var item in data.TableData)
            {
                switch (item.QualityGrade)
                {
                    case "3":
                        item.QualityGrade = "NG";
                        break;
                    case "2":
                        item.QualityGrade = "OK";
                        break;
                    case "1":
                        item.QualityGrade = "Good";
                        break;
                    default:
                        item.QualityGrade = "Unknown";
                        break;
                }
            }



            return data;
        }



        public UnitTraceDetailDtoOut GetUnitTraceDetail(string partSerialNumber)
        {

            var partUnit = String.IsNullOrEmpty(partSerialNumber) == true ? db.Part_Unit.OrderByDescending(a => a.Start_Time).FirstOrDefault() : db.Part_Unit.Where(a => a.Part_Serial == partSerialNumber).FirstOrDefault();
            if (partUnit == null)
            { return null; }
            decimal currentRate = 65.535M;
            decimal voltageRate = 655.35M;
            currentRate = Convert.ToDecimal(partUnit.Robot.Para1);
            voltageRate = Convert.ToDecimal(partUnit.Robot.Para2);
            var query = String.IsNullOrEmpty(partSerialNumber) == true ? db.Pass_Value_History.Where(a => a.Part_Serial == partUnit.Part_Serial).ToList() : db.Pass_Value_History.Where(a => a.Part_Serial == partSerialNumber).ToList();
            AutoMapper.Mapper.Initialize(cfg => cfg.CreateMap<Pass_Value_History, UnitPassTraceRowDto>()
            .ForMember(dest => dest.Current, src => src.MapFrom(s => s.Para_Value1))
        .ForMember(dest => dest.Voltage, src => src.MapFrom(s => s.Para_Value2))
         .ForMember(dest => dest.Speed, src => src.MapFrom(s => s.Para_Value3))
        .ForMember(dest => dest.Frequency, src => src.MapFrom(s => s.Weave_Value1))
        .ForMember(dest => dest.Amp, src => src.MapFrom(s => s.Weave_Value2))
        .ForMember(dest => dest.DwellL, src => src.MapFrom(s => s.Weave_Value3))
        .ForMember(dest => dest.DwellR, src => src.MapFrom(s => s.Weave_Value4))
          .ForMember(dest => dest.QualityGrade, src => src.MapFrom(s => s.Quality_Grade))
          .ForMember(dest => dest.PassNo, src => src.MapFrom(s => s.Pass_No))
          .ForMember(dest => dest.StartTime, src => src.MapFrom(s => s.Start_Time))
          .ForMember(dest => dest.EndTime, src => src.MapFrom(s => s.End_Time))
          .ForMember(dest => dest.InsertTime, src => src.MapFrom(s => s.Insert_Time))
          );

            UnitTraceDetailDtoOut data = new UnitTraceDetailDtoOut();
            data.PassData = AutoMapper.Mapper.Map<List<UnitPassTraceRowDto>>(query);
            data.PartSerial = partUnit.Part_Serial;
            foreach (var item in data.PassData)
            {
                Pass_Standard_Value standard = db.Pass_Standard_Value.Where(a => a.Part_Name == partUnit.Part_Name && a.Robot_ID == partUnit.Robot_ID && a.Pass_No == item.PassNo).FirstOrDefault();
                if (standard == null)
                {
                    return new UnitTraceDetailDtoOut() { BatchNo = "", PartSerial = "", PassData = null, QualityGrade = "", RobotNo = "" };
                }
                item.Current = decimal.Round(item.Current, 2);
                item.Voltage = decimal.Round(item.Voltage, 2);

                item.CurrentStandard = Decimal.Round(Convert.ToDecimal(standard.Current_Standard) / currentRate, 2);
                item.VoltageStandard = Decimal.Round(Convert.ToDecimal(standard.Voltage_Standard) / voltageRate, 2);

                item.CurrentLSL = decimal.Round(item.CurrentStandard - item.CurrentStandard * Convert.ToDecimal(standard.Current_Standard_Low_Percent) / 100, 2);
                item.CurrentUSL = decimal.Round(item.CurrentStandard + item.CurrentStandard * Convert.ToDecimal(standard.Current_Standard_High_Percent) / 100, 2);

                item.VoltageLSL = decimal.Round(item.VoltageStandard - item.VoltageStandard * Convert.ToDecimal(standard.Voltage_Standard_Low_Percent) / 100, 2);
                item.VoltageUSL = decimal.Round(item.VoltageStandard + item.VoltageStandard * Convert.ToDecimal(standard.Voltage_Standard_High_Percent) / 100, 2);
                switch (item.QualityGrade)
                {
                    case "1":
                        item.QualityGrade = "Good";
                        break;
                    case "2":
                        item.QualityGrade = "OK";
                        break;
                    case "3":
                        item.QualityGrade = "NG";
                        break;
                    default:
                        item.QualityGrade = "Unknown";
                        break;
                }
            }
            //DateTime before = partUnit.Start_Time.AddHours(-4);
            //DateTime after = partUnit.Start_Time.AddHours(4);
            //var alarms = db.Alarm_History.Where(a => a.Robot_ID == partUnit.Robot_ID && a.Time >= before && a.Time <= after).ToList();
            //AutoMapper.Mapper.Initialize(cfg => cfg.CreateMap<Alarm_History, AlarmRecordDTO>().ForMember(dest => dest.Robot_YH_No, src => src.MapFrom(s => s.Robot.YH_No)));
            //List<AlarmRecordDTO> alarmsDTO = AutoMapper.Mapper.Map<List<AlarmRecordDTO>>(alarms);
            //AlarmHistoryDTO alarmHistory = new AlarmHistoryDTO();
            //alarmHistory.AlarmRecords = alarmsDTO;
            //alarmHistory.Robot_YH_No = partUnit.Robot.YH_No;
            //data.Alarms = alarmHistory;

            //var robotStateChanges = db.Robot_State_Change_History.Where(a => a.Robot_ID == partUnit.Robot_ID && a.ChangeDateTime >= before && a.ChangeDateTime <= after).ToList();
            //AutoMapper.Mapper.Initialize(cfg => cfg.CreateMap<Robot_State_Change_History, RobotStateChangeRecordDto>().ForMember(dest => dest.Original_State_Type, src => src.MapFrom(s => s.Robot_State_Type.Type)).ForMember(dest => dest.Changed_State_Type, src => src.MapFrom(s => s.Robot_State_Type.Type)));
            //List<RobotStateChangeRecordDto> recordsDto = AutoMapper.Mapper.Map<List<RobotStateChangeRecordDto>>(robotStateChanges);
            //RobotStateChangeHistoryDtoOutput robotStateChangeHistory = new RobotStateChangeHistoryDtoOutput();
            //robotStateChangeHistory.Robot_YH_NO = partUnit.Robot.YH_No;
            //robotStateChangeHistory.RobotStateChangeRecords = recordsDto;
            //data.RobotStateChanges = robotStateChangeHistory;
            //data.RobotNo = partUnit.Robot.YH_No;
            //data.QualityGrade = partUnit.Quality_Grade == 1 ? "Good" : (partUnit.Quality_Grade == 2) ? "OK" : "NG";
            //data.BatchNo = partUnit.Batch;

            return data;
        }

        #region Pass Measurement Data
        public UnitMeasurementHistoryOnePart_SeialDtoOutput GetNoData()
        {
            DateTime today = System.DateTime.Now.Date;
            UnitMeasurementHistoryOnePart_SeialDtoOutput noData = new UnitMeasurementHistoryOnePart_SeialDtoOutput();
            noData.CurrentMax = 0;
            noData.OnePassMeasurementRecord = new UnitMeasurementHistoryOnePassNoDtoOutput
            {
                Current_TimePoint = new List<string> { "" },
                Data_Current = new List<decimal> { 0 },
                Data_Voltage = new List<decimal> { 0 },
                End_Time = today,
                Insert_Time = today,
                Para_Value1 = 0,
                Para_Value2 = 0,
                Para_Value3 = 0,
                Part_Number = "",
                Part_Serial = "",
                Pass_No = 0,
                Standard_Current_AVGLine = 0,
                Standard_Current_LSL = 0,
                Standard_Current_USL = 0,
                Standard_Voltage_AVGLine = 0,
                Standard_Voltage_LSL = 0,
                Standard_Voltage_USL = 0,
                Start_Time = today,
                Voltage_TimePoint = new List<string> { "" },
                Weave_Value1 = 0,
                Weave_Value2 = 0,
                Weave_Value3 = 0,
                Weave_Value4 = 0
            };
            noData.Part_Serial = "";
            noData.Pass_Nos = new List<int> { 0 };
            noData.QualityGrade = -1;
            noData.SerialNumbers = new List<string> { "" };
            noData.Standard_Data_Current = new List<decimal> { 0 };
            noData.Standard_Data_Voltage = new List<decimal> { 0 };
            noData.VoltageMax = 0;
            return noData;
        }

        public UnitMeasurementHistoryOnePart_SeialDtoOutput GetLastUnitMeasurementHistoryOfRobot(int robotId)
        {
            DateTime today = System.DateTime.Now.Date;
            var lastPart_SerialOfRobot = robotId == -1 ? db.Part_Unit.Where(a => a.Start_Time >= today).OrderByDescending(a => a.Start_Time).FirstOrDefault() : db.Part_Unit.Where(a => a.Robot_ID == robotId && a.Start_Time >= today).OrderByDescending(a => a.Start_Time).FirstOrDefault();

            if (lastPart_SerialOfRobot == null)
            {
                return GetNoData();
            }
            var passValueHistoryRecord = db.Pass_Value_History.Where(a => a.Part_Serial == lastPart_SerialOfRobot.Part_Serial && a.Pass_No == 1).FirstOrDefault();
            if (passValueHistoryRecord == null)
            {
                return GetNoData();
            }

            var data = GetUnitMeasurementHistoryByOnePartSerialAndPassNo(lastPart_SerialOfRobot.Part_Serial, 1);
            data.SerialNumbers = db.Part_Unit.Where(a => a.Robot_ID == robotId && a.Start_Time >= today).Select(a => a.Part_Serial).ToList();
            return data;
        }

        public UnitMeasurementHistoryOnePart_SeialDtoOutput GetUnitMeasurementHistoryByOnePartSerialAndPassNo(string part_Serial, int pass_No)
        {

            DateTime today = System.DateTime.Now.Date;
            Part_Unit partUnitInfo = db.Part_Unit.Where(a => a.Part_Serial == part_Serial).FirstOrDefault();
            if (partUnitInfo == null)
            {
                return GetNoData();
            }
            Pass_Value_History passValueHistoryRecord = db.Pass_Value_History.Where(a => a.Part_Serial == part_Serial && a.Pass_No == pass_No).FirstOrDefault();
            if (passValueHistoryRecord == null)
            {
                return GetNoData();
            }
            decimal currentRate = 65.535M;
            decimal voltageRate = 655.35M;
            currentRate = Convert.ToDecimal(partUnitInfo.Robot.Para1);
            voltageRate = Convert.ToDecimal(partUnitInfo.Robot.Para2);
            #region Wrap DTO
            UnitMeasurementHistoryOnePart_SeialDtoOutput data = new UnitMeasurementHistoryOnePart_SeialDtoOutput();

            #region OnePassNoUnitMeasurementData
            UnitMeasurementHistoryOnePassNoDtoOutput onePassNoData = new UnitMeasurementHistoryOnePassNoDtoOutput();
            onePassNoData.Part_Serial = part_Serial;
            onePassNoData.Part_Number = partUnitInfo.Part_Name;
            onePassNoData.End_Time = passValueHistoryRecord.End_Time;
            onePassNoData.Insert_Time = passValueHistoryRecord.Insert_Time;
            onePassNoData.Para_Value1 = passValueHistoryRecord.Para_Value1;
            onePassNoData.Para_Value2 = passValueHistoryRecord.Para_Value2;
            onePassNoData.Para_Value3 = passValueHistoryRecord.Para_Value3;
            onePassNoData.Part_Serial = passValueHistoryRecord.Part_Serial;
            onePassNoData.Pass_No = passValueHistoryRecord.Pass_No;
            onePassNoData.Start_Time = passValueHistoryRecord.Start_Time;
            onePassNoData.Weave_Value1 = passValueHistoryRecord.Weave_Value1;
            onePassNoData.Weave_Value2 = passValueHistoryRecord.Weave_Value2;
            onePassNoData.Weave_Value3 = passValueHistoryRecord.Weave_Value3;
            onePassNoData.Weave_Value4 = passValueHistoryRecord.Weave_Value4;
            onePassNoData.Current_Real_Over_Percent = passValueHistoryRecord.Current_Real_Over_Percent ?? 0;
            onePassNoData.Voltage_Real_Over_Percent = passValueHistoryRecord.Voltage_Real_Over_Percent ?? 0;

            TimeSpan totalTime = passValueHistoryRecord.End_Time - passValueHistoryRecord.Start_Time;
            string[] dataCurrent = passValueHistoryRecord.Data_Current.Split(',');
            long timeGapOfCurrent = totalTime.Ticks / dataCurrent.Length;
            List<decimal> dataCurrentDecimal = new List<decimal>();
            List<string> currentTimePoints = new List<string>();
            DateTime timePointCurrent = passValueHistoryRecord.Start_Time;
            int currentTimePoint = 0;
            foreach (string s in dataCurrent)
            {
                if (String.IsNullOrEmpty(s))
                { dataCurrentDecimal.Add(0); }
                else
                {
                    dataCurrentDecimal.Add(decimal.Round(decimal.Parse(s) / currentRate, 2));
                }
                //currentTimePoints.Add((timePointCurrent += new TimeSpan(timeGapOfCurrent)).ToString("HH:mm:ss.fff"));
                currentTimePoints.Add((0.024 * currentTimePoint).ToString());
                currentTimePoint++;
            }
            onePassNoData.Current_TimePoint = currentTimePoints;
            onePassNoData.Data_Current = dataCurrentDecimal;

            string[] dataVoltage = passValueHistoryRecord.Data_Voltage.Split(',');
            long timeGapOfVoltage = totalTime.Ticks / dataVoltage.Length;
            List<string> voltageTimePoints = new List<string>();
            DateTime timePointVoltage = passValueHistoryRecord.Start_Time;
            List<decimal> dataVoltageDecimal = new List<decimal>();
            int voltageTimePoint = 0;
            foreach (string s in dataVoltage)
            {
                if (String.IsNullOrEmpty(s))
                {
                    dataVoltageDecimal.Add(0);
                }
                else
                {
                    dataVoltageDecimal.Add(decimal.Round(decimal.Parse(s) / voltageRate, 2));
                }
                //voltageTimePoints.Add((timePointVoltage += new TimeSpan(timeGapOfVoltage)).ToString("HH:mm:ss.fff"));
                voltageTimePoints.Add((0.024 * voltageTimePoint).ToString());
                voltageTimePoint++;
            }
            onePassNoData.Voltage_TimePoint = voltageTimePoints;
            onePassNoData.Data_Voltage = dataVoltageDecimal;

            data.OnePassMeasurementRecord = onePassNoData;

            #endregion
            #region BenchMarkData
            var standardRecord = db.Pass_Standard_Value.Where(a => a.Part_Name == partUnitInfo.Part_Name && a.Pass_No == pass_No && a.Robot_ID == partUnitInfo.Robot_ID).FirstOrDefault();
            if (standardRecord == null)
            {
                data.Standard_Data_Current = data.OnePassMeasurementRecord.Data_Current;
                data.Standard_Data_Voltage = data.OnePassMeasurementRecord.Data_Voltage;
                data.OnePassMeasurementRecord.Standard_Current_AVGLine = 0;
                data.OnePassMeasurementRecord.Standard_Current_LSL = 0;
                data.OnePassMeasurementRecord.Standard_Current_USL = 0;
                data.OnePassMeasurementRecord.Standard_Voltage_AVGLine = 0;
                data.OnePassMeasurementRecord.Standard_Voltage_LSL = 0;
                data.OnePassMeasurementRecord.Standard_Voltage_USL = 0;
            }
            else
            {
                data.Standard_Data_Current = data.OnePassMeasurementRecord.Data_Current;
                data.Standard_Data_Voltage = data.OnePassMeasurementRecord.Data_Voltage;
                data.OnePassMeasurementRecord.Standard_Current_AVGLine = decimal.Round(Convert.ToDecimal(standardRecord.Current_Standard) / currentRate, 2);
                data.OnePassMeasurementRecord.Standard_Current_LSL = decimal.Round(Convert.ToDecimal(standardRecord.Current_Standard - standardRecord.Current_Standard * standardRecord.Current_Standard_Low_Percent / 100) / currentRate, 2);
                data.OnePassMeasurementRecord.Standard_Current_USL = decimal.Round(Convert.ToDecimal(standardRecord.Current_Standard + standardRecord.Current_Standard * standardRecord.Current_Standard_High_Percent / 100) / currentRate, 2);
                data.OnePassMeasurementRecord.Standard_Voltage_AVGLine = decimal.Round(Convert.ToDecimal(standardRecord.Voltage_Standard) / voltageRate, 2);
                data.OnePassMeasurementRecord.Standard_Voltage_LSL = decimal.Round(Convert.ToDecimal(standardRecord.Voltage_Standard - standardRecord.Voltage_Standard * standardRecord.Voltage_Standard_Low_Percent / 100) / voltageRate, 2);
                data.OnePassMeasurementRecord.Standard_Voltage_USL = decimal.Round(Convert.ToDecimal(standardRecord.Voltage_Standard + standardRecord.Voltage_Standard * standardRecord.Voltage_Standard_High_Percent / 100) / voltageRate, 2);

                string[] standardDataCurrent = standardRecord.Data_Current.Split(',');
                List<decimal> standardDataCurrentList = new List<decimal>();
                foreach (string s in standardDataCurrent)
                {
                    if (String.IsNullOrEmpty(s))
                    { standardDataCurrentList.Add(0); }
                    else
                    {
                        standardDataCurrentList.Add(decimal.Round(decimal.Parse(s) / currentRate, 2));
                    }
                }
                data.Standard_Data_Current = standardDataCurrentList;

                string[] standardDataVoltage = standardRecord.Data_Voltage.Split(',');
                List<decimal> standardDataVoltageList = new List<decimal>();
                foreach (string s in standardDataVoltage)
                {
                    if (String.IsNullOrEmpty(s))
                    {
                        standardDataVoltageList.Add(0);
                    }
                    else
                    {
                        standardDataVoltageList.Add(decimal.Round(decimal.Parse(s) / voltageRate, 2));
                    }
                }
            }
            #endregion
            #region Outer data
            #region Get all Pass_Nos And Quality Grades
            var pass_NosAndQualityGrades = from a in db.Pass_Value_History.Where(a => a.Part_Serial == part_Serial) select new { Pass_No = a.Pass_No, QualityGrade = a.Quality_Grade };
            data.Part_Serial = part_Serial;
            data.Pass_Nos = new List<int>();
            data.Passes_QualityGrade = new List<OnePassQualityResultRowDtoOutput>();
            foreach (var item in pass_NosAndQualityGrades)
            {
                data.Pass_Nos.Add(item.Pass_No);
                data.Passes_QualityGrade.Add(new OnePassQualityResultRowDtoOutput() { Pass_No = item.Pass_No, QualityGrade = item.QualityGrade });
            }
            #endregion
            data.QualityGrade = passValueHistoryRecord.Quality_Grade;
            data.SerialNumbers = new List<string>();
            data.SerialNumbers = db.Part_Unit.Where(a => a.Start_Time >= today).Select(a => a.Part_Serial).ToList();
            decimal currentMaxValue = data.OnePassMeasurementRecord.Data_Current.Max() >= data.Standard_Data_Current.Max() ? data.OnePassMeasurementRecord.Data_Current.Max() : data.Standard_Data_Current.Max();
            decimal voltageMaxValue = data.OnePassMeasurementRecord.Data_Voltage.Max() >= data.Standard_Data_Voltage.Max() ? data.OnePassMeasurementRecord.Data_Voltage.Max() : data.Standard_Data_Voltage.Max();
            data.CurrentMax = currentMaxValue;
            data.VoltageMax = voltageMaxValue;
            #endregion
            #endregion

            return data;
        }
        #endregion

        public AlarmHistoryDtoOut GetRelativeAlarmHistoryByPartSerial(string partSerial, int hours = 4)
        {
            var partUnit = db.Part_Unit.Where(a => a.Part_Serial == partSerial).FirstOrDefault();

            if (partUnit == null)
            {
                return null;
            }
            DateTime partUnitBuiltTime = partUnit.Start_Time;
            DateTime before = partUnitBuiltTime.AddHours(0 - hours);
            DateTime after = partUnitBuiltTime.AddHours(hours);
            var alarms = db.Alarm_History.Where(a => a.Robot_ID == partUnit.Robot_ID && a.Time >= before && a.Time <= after).ToList();
            if (alarms.Count <= 0)
            {
                return null;
            }
            AutoMapper.Mapper.Initialize(cfg => cfg.CreateMap<Alarm_History, AlarmRecordDTO>().ForMember(dest => dest.Robot_YH_No, src => src.MapFrom(s => s.Robot.YH_No)));
            List<AlarmRecordDTO> alarmsDTO = AutoMapper.Mapper.Map<List<AlarmRecordDTO>>(alarms);
            AlarmHistoryDtoOut data = new AlarmHistoryDtoOut();
            data.AlarmRecords = alarmsDTO;
            data.Robot_YH_No = partUnit.Robot.YH_No;

            return data;
        }
        public AlarmHistoryDtoOut GetAlarmsHistory(AlarmSearchDtoIn input)
        {
            var alarms = db.Alarm_History.Where(a =>
            (String.IsNullOrEmpty(input.Alarm_Cause) == true ? true : a.Alarm_Cause == input.Alarm_Cause) &&
             (String.IsNullOrEmpty(input.Alarm_Code) == true ? true : a.Alarm_Code == input.Alarm_Code) &&
               (String.IsNullOrEmpty(input.Alarm_Message) == true ? true : a.Alarm_Message == input.Alarm_Message) &&
               (String.IsNullOrEmpty(input.Alarm_Severity) == true ? true : a.Alarm_Severity == input.Alarm_Severity) &&
               (input.StartTime == null ? true : a.Time >= input.StartTime) &&
               (input.EndTime == null ? true : a.Time <= input.EndTime)
            ).OrderByDescending(a => a.Time).ToList();
            if (alarms.Count <= 0)
            {
                return null;
            }
            AutoMapper.Mapper.Initialize(cfg => cfg.CreateMap<Alarm_History, AlarmRecordDTO>().ForMember(dest => dest.Robot_YH_No, src => src.MapFrom(s => s.Robot.YH_No)));
            List<AlarmRecordDTO> alarmsDTO = AutoMapper.Mapper.Map<List<AlarmRecordDTO>>(alarms);
            AlarmHistoryDtoOut data = new AlarmHistoryDtoOut();
            data.AlarmRecords = alarmsDTO;
            data.Robot_YH_No = alarms.FirstOrDefault().Robot.YH_No;

            return data;
        }

        public RobotStateChangeHistoryDtoOutput GetRelativeRobotStateChangeHistoryByPartSerial(string partSerial, int hours = 4)
        {
            var partUnit = db.Part_Unit.Where(a => a.Part_Serial == partSerial).FirstOrDefault();

            if (partUnit == null)
            {
                return null;
            }
            DateTime partUnitBuiltTime = partUnit.Start_Time;
            DateTime before = partUnitBuiltTime.AddHours(0 - hours);
            DateTime after = partUnitBuiltTime.AddHours(hours);

            var robotStateChangeHistory = db.Robot_State_Change_History.Where(a => a.Robot_ID == partUnit.Robot_ID && a.ChangeDateTime >= before && a.ChangeDateTime <= after).ToList();

            AutoMapper.Mapper.Initialize(cfg => cfg.CreateMap<Robot_State_Change_History, RobotStateChangeRecordDto>().ForMember(dest => dest.Robot_YH_NO, src => src.MapFrom(s => s.Robot.YH_No)));
            List<RobotStateChangeRecordDto> recordsDto = AutoMapper.Mapper.Map<List<RobotStateChangeRecordDto>>(robotStateChangeHistory);
            RobotStateChangeHistoryDtoOutput data = new RobotStateChangeHistoryDtoOutput();
            foreach (var item in recordsDto)
            {
                switch (item.Original_State_Type)
                {
                    case "1":
                        item.Original_State_Type = "PowerOff";
                        break;
                    case "2":
                        item.Original_State_Type = "Fault";
                        break;
                    case "3":
                        item.Original_State_Type = "Ready";
                        break;
                    case "4":
                        item.Original_State_Type = "Running";
                        break;
                    default:
                        item.Original_State_Type = "Unkonown";
                        break;
                }
                switch (item.Changed_State_Type)
                {
                    case "1":
                        item.Changed_State_Type = "PowerOff";
                        break;
                    case "2":
                        item.Changed_State_Type = "Fault";
                        break;
                    case "3":
                        item.Changed_State_Type = "Ready";
                        break;
                    case "4":
                        item.Changed_State_Type = "Running";
                        break;
                    default:
                        item.Changed_State_Type = "Unkonown";
                        break;
                }
            }

            data.Robot_YH_NO = partUnit.Robot.YH_No;
            data.RobotStateChangeRecords = recordsDto;

            return data;
        }

        public RobotStateChangeHistoryDtoOutput GetRobotStateChanges(RobotStateChangeSearchDtoIn input)
        {
            var robotStateChangeHistory = db.Robot_State_Change_History.Where(a =>
             (String.IsNullOrEmpty(input.Robot_YH_NO) == true ? true : a.Robot.YH_No == input.Robot_YH_NO) &&
            (input.Original_State_Type == null ? true : a.Original_State_Type == input.Original_State_Type) &&
              (input.Changed_State_Type == null ? true : a.Changed_State_Type == input.Changed_State_Type) &&
              (input.StartTime == null ? true : a.ChangeDateTime >= input.StartTime) &&
              (input.EndTime == null ? true : a.ChangeDateTime <= input.EndTime)
            ).ToList();
            if (robotStateChangeHistory.Count <= 0)
            {
                return null;
            }
            AutoMapper.Mapper.Initialize(cfg => cfg.CreateMap<Robot_State_Change_History, RobotStateChangeRecordDto>().ForMember(dest => dest.Robot_YH_NO, src => src.MapFrom(s => s.Robot.YH_No)));
            List<RobotStateChangeRecordDto> recordsDto = AutoMapper.Mapper.Map<List<RobotStateChangeRecordDto>>(robotStateChangeHistory);
            RobotStateChangeHistoryDtoOutput data = new RobotStateChangeHistoryDtoOutput();
            foreach (var item in recordsDto)
            {
                switch (item.Original_State_Type)
                {
                    case "1":
                        item.Original_State_Type = "PowerOff";
                        break;
                    case "2":
                        item.Original_State_Type = "Fault";
                        break;
                    case "3":
                        item.Original_State_Type = "Ready";
                        break;
                    case "4":
                        item.Original_State_Type = "Running";
                        break;
                    default:
                        item.Original_State_Type = "Unkonown";
                        break;
                }
                switch (item.Changed_State_Type)
                {
                    case "1":
                        item.Changed_State_Type = "PowerOff";
                        break;
                    case "2":
                        item.Changed_State_Type = "Fault";
                        break;
                    case "3":
                        item.Changed_State_Type = "Ready";
                        break;
                    case "4":
                        item.Changed_State_Type = "Running";
                        break;
                    default:
                        item.Changed_State_Type = "Unkonown";
                        break;
                }
            }
            data.Robot_YH_NO = robotStateChangeHistory.First().Robot.YH_No;
            data.RobotStateChangeRecords = recordsDto;

            return data;
        }

        public ParameterChangesDtoOut GetRelativeParameterChangeHistory(string partSerial, int hours = 4)
        {
            var partUnit = db.Part_Unit.Where(a => a.Part_Serial == partSerial).FirstOrDefault();

            if (partUnit == null)
            {
                return null;
            }
            DateTime partUnitBuiltTime = partUnit.Start_Time;
            DateTime before = partUnitBuiltTime.AddHours(0 - hours);
            DateTime after = partUnitBuiltTime.AddHours(hours);
            var parameterChangeHistory = db.Parameter_Version.Where(a => a.Para_Update_Time >= before && a.Para_Update_Time <= after && a.Robot_ID == partUnit.Robot_ID).ToList();
            AutoMapper.Mapper.Initialize(cfg => cfg.CreateMap<Parameter_Version, ParameterChangesRowDtoOut>().ForMember(dest => dest.Robot_YH_No, src => src.MapFrom(s => s.Robot.YH_No)));
            List<ParameterChangesRowDtoOut> parameterChangesHistoryDto = AutoMapper.Mapper.Map<List<ParameterChangesRowDtoOut>>(parameterChangeHistory);
            ParameterChangesDtoOut data = new ParameterChangesDtoOut();
            data.ParameterChangeRecords = parameterChangesHistoryDto;
            data.Robot_YH_No = partUnit.Robot.YH_No;

            return data;
        }

        public ParameterChangesDtoOut GetParameterChanges(ParameterChangesSearchDtoIn input)
        {
            var parameterChangeHistory = db.Parameter_Version.Where(a =>
            (String.IsNullOrEmpty(input.Checked_By) == true ? true : a.Checked_By == input.Checked_By) &&
            (String.IsNullOrEmpty(input.Robot_YH_No) == true ? true : a.Checked_By == input.Robot_YH_No) &&
            (String.IsNullOrEmpty(input.Version_No) == true ? true : a.Checked_By == input.Version_No) &&
            (input.State == null ? true : a.State == input.State) &&
            (input.StartTime == null ? true : a.Para_Update_Time >= input.StartTime) &&
             (input.EndTime == null ? true : a.Para_Update_Time <= input.EndTime)
            ).ToList();
            if (parameterChangeHistory.Count() <= 0)
            {
                return null;
            }
            AutoMapper.Mapper.Initialize(cfg => cfg.CreateMap<Parameter_Version, ParameterChangesRowDtoOut>().ForMember(dest => dest.Robot_YH_No, src => src.MapFrom(s => s.Robot.YH_No)));
            List<ParameterChangesRowDtoOut> parameterChangesHistoryDto = AutoMapper.Mapper.Map<List<ParameterChangesRowDtoOut>>(parameterChangeHistory);
            ParameterChangesDtoOut data = new ParameterChangesDtoOut();
            data.ParameterChangeRecords = parameterChangesHistoryDto;
            data.Robot_YH_No = parameterChangeHistory.First().Robot.YH_No;

            return data;
        }

        #region 2017-Oct new features
        #region Polish measurement data
        public PolishMeasurementDataForOnePartDtoOut GetNoDataOfPolishMeasurement()
        {
            DateTime today = System.DateTime.Now.Date;
            PolishMeasurementDataForOnePartDtoOut noData = new PolishMeasurementDataForOnePartDtoOut();
            noData.Part_Serial = "";
            noData.Start_Time = today;
            noData.End_Time = today;
            noData.Insert_Time = today;
            noData.J1CurrentLSL = 0;
            noData.J1CurrentUSL = 0;
            noData.J1CurrentAbsAvg = 0;
            noData.J1_Current = new List<decimal> { 0 };
            noData.J1_Current_TimePoints = new List<string> { "" };
            noData.J2CurrentLSL = 0;
            noData.J2CurrentUSL = 0;
            noData.J2CurrentAbsAvg = 0;
            noData.J2_Current = new List<decimal> { 0 };
            noData.J2_Current_TimePoints = new List<string> { "" };
            noData.J3CurrentLSL = 0;
            noData.J3CurrentUSL = 0;
            noData.J3CurrentAbsAvg = 0;
            noData.J3_Current = new List<decimal> { 0 };
            noData.J3_Current_TimePoints = new List<string> { "" };
            noData.J4CurrentLSL = 0;
            noData.J4CurrentUSL = 0;
            noData.J4CurrentAbsAvg = 0;
            noData.J4_Current = new List<decimal> { 0 };
            noData.J4_Current_TimePoints = new List<string> { "" };
            noData.J5CurrentLSL = 0;
            noData.J5CurrentUSL = 0;
            noData.J5CurrentAbsAvg = 0;
            noData.J5_Current = new List<decimal> { 0 };
            noData.J5_Current_TimePoints = new List<string> { "" };
            noData.J6CurrentLSL = 0;
            noData.J6CurrentUSL = 0;
            noData.J6CurrentAbsAvg = 0;
            noData.J6_Current = new List<decimal> { 0 };
            noData.J6_Current_TimePoints = new List<string> { "" };
            return noData;
        }
        /// <summary>
        /// Get last plish measurement data of one robot
        /// </summary>
        /// <param name="robotId">Robot Id</param>
        /// <returns>PolishMeasurementDataForOnePartDtoOut</returns>
        public PolishMeasurementDataForOnePartDtoOut GetLastPolishMeasurementDataForPartOfRobot(int robotId)
        {
            DateTime today = System.DateTime.Now.Date;
            var lastPart_SerialOfRobot = robotId == -1 ? db.Polish_Part_Unit.Where(a => a.Start_Time >= today).OrderByDescending(a => a.Start_Time).FirstOrDefault() : db.Polish_Part_Unit.Where(a => a.Robot_ID == robotId && a.Start_Time >= today).OrderByDescending(a => a.Start_Time).FirstOrDefault();

            if (lastPart_SerialOfRobot == null)
            {
                return GetNoDataOfPolishMeasurement();
            }
            return GetPolishMeasurementDataByPartSerial(lastPart_SerialOfRobot.Part_Serial);
        }
        /// <summary>
        /// Get polish measurement data by part serial number
        /// </summary>
        /// <param name="part_Serial">Part serial number</param>
        /// <returns>PolishMeasurementDataForOnePartDtoOut</returns>
        public PolishMeasurementDataForOnePartDtoOut GetPolishMeasurementDataByPartSerial(string part_Serial)
        {
            DateTime today = System.DateTime.Now.Date;
            var lastPart_SerialOfRobot = db.Polish_Part_Unit.Where(a => a.Part_Serial == part_Serial).OrderByDescending(a => a.Start_Time).FirstOrDefault();

            if (lastPart_SerialOfRobot == null)
            {
                return GetNoDataOfPolishMeasurement();
            }
            var partMeasurementData = db.Polish_Axis.Where(a => a.Part_ID == lastPart_SerialOfRobot.ID).FirstOrDefault();
            if (partMeasurementData == null)
            {
                return GetNoDataOfPolishMeasurement();
            }

            List<string> currentTimePoints = new List<string>();
            string[] j1currentData = partMeasurementData.J1_Current.Split(',');
            string[] j2currentData = partMeasurementData.J2_Current.Split(',');
            string[] j3currentData = partMeasurementData.J3_Current.Split(',');
            string[] j4currentData = partMeasurementData.J4_Current.Split(',');
            string[] j5currentData = partMeasurementData.J5_Current.Split(',');
            string[] j6currentData = partMeasurementData.J6_Current.Split(',');
            List<decimal> j1currentDataDecimal = new List<decimal>();
            List<decimal> j2currentDataDecimal = new List<decimal>();
            List<decimal> j3currentDataDecimal = new List<decimal>();
            List<decimal> j4currentDataDecimal = new List<decimal>();
            List<decimal> j5currentDataDecimal = new List<decimal>();
            List<decimal> j6currentDataDecimal = new List<decimal>();

            int currentTimePoint = 0;
            foreach (string s in j1currentData)
            {
                if (String.IsNullOrEmpty(s))
                { j1currentDataDecimal.Add(0); }
                else
                {
                    j1currentDataDecimal.Add(decimal.Round(decimal.Parse(s) / 1, 2));
                }
                currentTimePoints.Add((1.08 * currentTimePoint).ToString());
                currentTimePoint++;
            }
            foreach (string s in j2currentData)
            {
                if (String.IsNullOrEmpty(s))
                { j2currentDataDecimal.Add(0); }
                else
                {
                    j2currentDataDecimal.Add(decimal.Round(decimal.Parse(s) / 1, 2));
                }
            }
            foreach (string s in j3currentData)
            {
                if (String.IsNullOrEmpty(s))
                { j3currentDataDecimal.Add(0); }
                else
                {
                    j3currentDataDecimal.Add(decimal.Round(decimal.Parse(s) / 1, 2));
                }
            }
            foreach (string s in j4currentData)
            {
                if (String.IsNullOrEmpty(s))
                { j4currentDataDecimal.Add(0); }
                else
                {
                    j4currentDataDecimal.Add(decimal.Round(decimal.Parse(s) / 1, 2));
                }
            }
            foreach (string s in j5currentData)
            {
                if (String.IsNullOrEmpty(s))
                { j5currentDataDecimal.Add(0); }
                else
                {
                    j5currentDataDecimal.Add(decimal.Round(decimal.Parse(s) / 1, 2));
                }
            }
            foreach (string s in j6currentData)
            {
                if (String.IsNullOrEmpty(s))
                { j6currentDataDecimal.Add(0); }
                else
                {
                    j6currentDataDecimal.Add(decimal.Round(decimal.Parse(s) / 1, 2));
                }
            }
            #region Wrap Data
            PolishMeasurementDataForOnePartDtoOut data = new PolishMeasurementDataForOnePartDtoOut();
            data.End_Time = lastPart_SerialOfRobot.End_Time;
            data.Start_Time = lastPart_SerialOfRobot.Start_Time;
            data.Insert_Time = lastPart_SerialOfRobot.Insert_Time;
            data.Part_Serial = lastPart_SerialOfRobot.Part_Serial;
            data.J1CurrentLSL = lastPart_SerialOfRobot.Min_Allowance_J1 == null ? 0 : Convert.ToDecimal(lastPart_SerialOfRobot.Min_Allowance_J1);
            data.J1CurrentUSL = lastPart_SerialOfRobot.Max_Allowance_J1 == null ? 0 : Convert.ToDecimal(lastPart_SerialOfRobot.Max_Allowance_J1);
            data.J2CurrentLSL = lastPart_SerialOfRobot.Min_Allowance_J2 == null ? 0 : Convert.ToDecimal(lastPart_SerialOfRobot.Min_Allowance_J2);
            data.J2CurrentUSL = lastPart_SerialOfRobot.Max_Allowance_J2 == null ? 0 : Convert.ToDecimal(lastPart_SerialOfRobot.Max_Allowance_J2);
            data.J3CurrentLSL = lastPart_SerialOfRobot.Min_Allowance_J3 == null ? 0 : Convert.ToDecimal(lastPart_SerialOfRobot.Min_Allowance_J3);
            data.J3CurrentUSL = lastPart_SerialOfRobot.Max_Allowance_J3 == null ? 0 : Convert.ToDecimal(lastPart_SerialOfRobot.Max_Allowance_J3);
            data.J4CurrentLSL = lastPart_SerialOfRobot.Min_Allowance_J4 == null ? 0 : Convert.ToDecimal(lastPart_SerialOfRobot.Min_Allowance_J4);
            data.J4CurrentUSL = lastPart_SerialOfRobot.Max_Allowance_J4 == null ? 0 : Convert.ToDecimal(lastPart_SerialOfRobot.Max_Allowance_J4);
            data.J5CurrentLSL = lastPart_SerialOfRobot.Min_Allowance_J5 == null ? 0 : Convert.ToDecimal(lastPart_SerialOfRobot.Min_Allowance_J5);
            data.J5CurrentUSL = lastPart_SerialOfRobot.Max_Allowance_J5 == null ? 0 : Convert.ToDecimal(lastPart_SerialOfRobot.Max_Allowance_J5);
            data.J6CurrentLSL = lastPart_SerialOfRobot.Min_Allowance_J6 == null ? 0 : Convert.ToDecimal(lastPart_SerialOfRobot.Min_Allowance_J6);
            data.J6CurrentUSL = lastPart_SerialOfRobot.Max_Allowance_J6 == null ? 0 : Convert.ToDecimal(lastPart_SerialOfRobot.Max_Allowance_J6);
            data.J1_Current_TimePoints = currentTimePoints;
            data.J2_Current_TimePoints = currentTimePoints;
            data.J3_Current_TimePoints = currentTimePoints;
            data.J4_Current_TimePoints = currentTimePoints;
            data.J5_Current_TimePoints = currentTimePoints;
            data.J6_Current_TimePoints = currentTimePoints;
            data.J1_Current = j1currentDataDecimal;
            data.J2_Current = j2currentDataDecimal;
            data.J3_Current = j3currentDataDecimal;
            data.J4_Current = j4currentDataDecimal;
            data.J5_Current = j5currentDataDecimal;
            data.J6_Current = j6currentDataDecimal;

            if (data.J1_Current != null)
            {
                decimal absTotal = 0;
                foreach (var item in data.J1_Current)
                {
                    absTotal += Math.Abs(item);
                }
                data.J1CurrentAbsAvg = Math.Round(absTotal / data.J1_Current.Count, 2);
            }
            else
            { data.J1CurrentAbsAvg = 0; }

            if (data.J2_Current != null)
            {
                decimal absTotal = 0;
                foreach (var item in data.J2_Current)
                {
                    absTotal += Math.Abs(item);
                }
                data.J2CurrentAbsAvg = Math.Round(absTotal / data.J2_Current.Count, 2);
            }
            else
            { data.J2CurrentAbsAvg = 0; }

            if (data.J3_Current != null)
            {
                decimal absTotal = 0;
                foreach (var item in data.J3_Current)
                {
                    absTotal += Math.Abs(item);
                }
                data.J3CurrentAbsAvg = Math.Round(absTotal / data.J3_Current.Count, 2);
            }
            else
            { data.J3CurrentAbsAvg = 0; }

            if (data.J4_Current != null)
            {
                decimal absTotal = 0;
                foreach (var item in data.J4_Current)
                {
                    absTotal += Math.Abs(item);
                }
                data.J4CurrentAbsAvg = Math.Round(absTotal / data.J4_Current.Count, 2);
            }
            else
            { data.J4CurrentAbsAvg = 0; }

            if (data.J5_Current != null)
            {
                decimal absTotal = 0;
                foreach (var item in data.J5_Current)
                {
                    absTotal += Math.Abs(item);
                }
                data.J5CurrentAbsAvg = Math.Round(absTotal / data.J5_Current.Count, 2);
            }
            else
            { data.J5CurrentAbsAvg = 0; }

            if (data.J6_Current != null)
            {
                decimal absTotal = 0;
                foreach (var item in data.J6_Current)
                {
                    absTotal += Math.Abs(item);
                }
                data.J6CurrentAbsAvg = Math.Round(absTotal / data.J6_Current.Count, 2);
            }
            else
            { data.J6CurrentAbsAvg = 0; }
            #endregion

            return data;

        }
        #endregion
        #region Press measurement data
        public PressMeasurementDataForOnePartDtoOut GetNoDataOfPressMeasurement()
        {
            DateTime today = System.DateTime.Now.Date;
            PressMeasurementDataForOnePartDtoOut noData = new PressMeasurementDataForOnePartDtoOut();
            noData.Part_Serial = "";
            noData.Start_Time = today;
            noData.End_Time = today;
            noData.Insert_Time = today;
            noData.Beat = 0;
            noData.J1CurrentLSL = 0;
            noData.J1CurrentUSL = 0;
            noData.J1CurrentAbsAvg = 0;
            noData.J1_Current = new List<decimal> { 0 };
            noData.J1_Current_TimePoints = new List<string> { "" };
            noData.J2CurrentLSL = 0;
            noData.J2CurrentUSL = 0;
            noData.J2CurrentAbsAvg = 0;
            noData.J2_Current = new List<decimal> { 0 };
            noData.J2_Current_TimePoints = new List<string> { "" };
            noData.J3CurrentLSL = 0;
            noData.J3CurrentUSL = 0;
            noData.J3CurrentAbsAvg = 0;
            noData.J3_Current = new List<decimal> { 0 };
            noData.J3_Current_TimePoints = new List<string> { "" };
            noData.J4CurrentLSL = 0;
            noData.J4CurrentUSL = 0;
            noData.J4CurrentAbsAvg = 0;
            noData.J4_Current = new List<decimal> { 0 };
            noData.J4_Current_TimePoints = new List<string> { "" };
            noData.J5CurrentLSL = 0;
            noData.J5CurrentUSL = 0;
            noData.J5CurrentAbsAvg = 0;
            noData.J5_Current = new List<decimal> { 0 };
            noData.J5_Current_TimePoints = new List<string> { "" };
            noData.J6CurrentLSL = 0;
            noData.J6CurrentUSL = 0;
            noData.J6CurrentAbsAvg = 0;
            noData.J6_Current = new List<decimal> { 0 };
            noData.J6_Current_TimePoints = new List<string> { "" };
            return noData;
        }
        /// <summary>
        /// Get last plish measurement data of one robot
        /// </summary>
        /// <param name="robotId">Robot Id</param>
        /// <returns>PressMeasurementDataForOnePartDtoOut</returns>
        public PressMeasurementDataForOnePartDtoOut GetLastPressMeasurementDataForPartOfRobot(int robotId)
        {
            DateTime today = System.DateTime.Now.Date;
            var lastPart_SerialOfRobot = robotId == -1 ? db.Press_Part_Unit.Where(a => a.Start_Time >= today).OrderByDescending(a => a.Start_Time).FirstOrDefault() : db.Press_Part_Unit.Where(a => a.Robot_ID == robotId && a.Start_Time >= today).OrderByDescending(a => a.Start_Time).FirstOrDefault();

            if (lastPart_SerialOfRobot == null)
            {
                return GetNoDataOfPressMeasurement();
            }
            return GetPressMeasurementDataByPartSerial(lastPart_SerialOfRobot.Part_Serial);
        }
        /// <summary>
        /// Get Press measurement data by part serial number
        /// </summary>
        /// <param name="part_Serial">Part serial number</param>
        /// <returns>PressMeasurementDataForOnePartDtoOut</returns>
        public PressMeasurementDataForOnePartDtoOut GetPressMeasurementDataByPartSerial(string part_Serial)
        {
            DateTime today = System.DateTime.Now.Date;
            var lastPart_SerialOfRobot = db.Press_Part_Unit.Where(a => a.Part_Serial == part_Serial).OrderByDescending(a => a.Start_Time).FirstOrDefault();

            if (lastPart_SerialOfRobot == null)
            {
                return GetNoDataOfPressMeasurement();
            }
            var partMeasurementData = db.Press_Axis.Where(a => a.Part_ID == lastPart_SerialOfRobot.ID).FirstOrDefault();
            if (partMeasurementData == null)
            {
                return GetNoDataOfPressMeasurement();
            }
            var pressLineRobot = db.Press_Line_Robots.Where(a => a.Robot_ID == lastPart_SerialOfRobot.Robot_ID).FirstOrDefault();
            if (pressLineRobot == null)
            {
                return GetNoDataOfPressMeasurement();
            }


            List<string> currentTimePoints = new List<string>();
            string[] j1currentData = partMeasurementData.J1_Current.Split(',');
            string[] j2currentData = partMeasurementData.J2_Current.Split(',');
            string[] j3currentData = partMeasurementData.J3_Current.Split(',');
            string[] j4currentData = partMeasurementData.J4_Current.Split(',');
            string[] j5currentData = partMeasurementData.J5_Current.Split(',');
            string[] j6currentData = partMeasurementData.J6_Current.Split(',');
            List<decimal> j1currentDataDecimal = new List<decimal>();
            List<decimal> j2currentDataDecimal = new List<decimal>();
            List<decimal> j3currentDataDecimal = new List<decimal>();
            List<decimal> j4currentDataDecimal = new List<decimal>();
            List<decimal> j5currentDataDecimal = new List<decimal>();
            List<decimal> j6currentDataDecimal = new List<decimal>();

            int currentTimePoint = 0;
            foreach (string s in j1currentData)
            {
                if (String.IsNullOrEmpty(s))
                { j1currentDataDecimal.Add(0); }
                else
                {
                    j1currentDataDecimal.Add(decimal.Round(decimal.Parse(s) / 1, 2));
                }
                currentTimePoints.Add((1.08 * currentTimePoint).ToString());
                currentTimePoint++;
            }
            foreach (string s in j2currentData)
            {
                if (String.IsNullOrEmpty(s))
                { j2currentDataDecimal.Add(0); }
                else
                {
                    j2currentDataDecimal.Add(decimal.Round(decimal.Parse(s) / 1, 2));
                }
            }
            foreach (string s in j3currentData)
            {
                if (String.IsNullOrEmpty(s))
                { j3currentDataDecimal.Add(0); }
                else
                {
                    j3currentDataDecimal.Add(decimal.Round(decimal.Parse(s) / 1, 2));
                }
            }
            foreach (string s in j4currentData)
            {
                if (String.IsNullOrEmpty(s))
                { j4currentDataDecimal.Add(0); }
                else
                {
                    j4currentDataDecimal.Add(decimal.Round(decimal.Parse(s) / 1, 2));
                }
            }
            foreach (string s in j5currentData)
            {
                if (String.IsNullOrEmpty(s))
                { j5currentDataDecimal.Add(0); }
                else
                {
                    j5currentDataDecimal.Add(decimal.Round(decimal.Parse(s) / 1, 2));
                }
            }
            foreach (string s in j6currentData)
            {
                if (String.IsNullOrEmpty(s))
                { j6currentDataDecimal.Add(0); }
                else
                {
                    j6currentDataDecimal.Add(decimal.Round(decimal.Parse(s) / 1, 2));
                }
            }
            #region Wrap Data
            PressMeasurementDataForOnePartDtoOut data = new PressMeasurementDataForOnePartDtoOut();
            data.End_Time = lastPart_SerialOfRobot.End_Time;
            data.Start_Time = lastPart_SerialOfRobot.Start_Time;
            data.Insert_Time = lastPart_SerialOfRobot.Insert_Time;
            data.Part_Serial = lastPart_SerialOfRobot.Part_Serial;
            data.Beat = pressLineRobot.Press_Line.Beat ?? 0;
            data.J1CurrentLSL = lastPart_SerialOfRobot.Min_Allowance_J1 == null ? 0 : Convert.ToDecimal(lastPart_SerialOfRobot.Min_Allowance_J1);
            data.J1CurrentUSL = lastPart_SerialOfRobot.Max_Allowance_J1 == null ? 0 : Convert.ToDecimal(lastPart_SerialOfRobot.Max_Allowance_J1);
            data.J2CurrentLSL = lastPart_SerialOfRobot.Min_Allowance_J2 == null ? 0 : Convert.ToDecimal(lastPart_SerialOfRobot.Min_Allowance_J2);
            data.J2CurrentUSL = lastPart_SerialOfRobot.Max_Allowance_J2 == null ? 0 : Convert.ToDecimal(lastPart_SerialOfRobot.Max_Allowance_J2);
            data.J3CurrentLSL = lastPart_SerialOfRobot.Min_Allowance_J3 == null ? 0 : Convert.ToDecimal(lastPart_SerialOfRobot.Min_Allowance_J3);
            data.J3CurrentUSL = lastPart_SerialOfRobot.Max_Allowance_J3 == null ? 0 : Convert.ToDecimal(lastPart_SerialOfRobot.Max_Allowance_J3);
            data.J4CurrentLSL = lastPart_SerialOfRobot.Min_Allowance_J4 == null ? 0 : Convert.ToDecimal(lastPart_SerialOfRobot.Min_Allowance_J4);
            data.J4CurrentUSL = lastPart_SerialOfRobot.Max_Allowance_J4 == null ? 0 : Convert.ToDecimal(lastPart_SerialOfRobot.Max_Allowance_J4);
            data.J5CurrentLSL = lastPart_SerialOfRobot.Min_Allowance_J5 == null ? 0 : Convert.ToDecimal(lastPart_SerialOfRobot.Min_Allowance_J5);
            data.J5CurrentUSL = lastPart_SerialOfRobot.Max_Allowance_J5 == null ? 0 : Convert.ToDecimal(lastPart_SerialOfRobot.Max_Allowance_J5);
            data.J6CurrentLSL = lastPart_SerialOfRobot.Min_Allowance_J6 == null ? 0 : Convert.ToDecimal(lastPart_SerialOfRobot.Min_Allowance_J6);
            data.J6CurrentUSL = lastPart_SerialOfRobot.Max_Allowance_J6 == null ? 0 : Convert.ToDecimal(lastPart_SerialOfRobot.Max_Allowance_J6);
            data.J1_Current_TimePoints = currentTimePoints;
            data.J2_Current_TimePoints = currentTimePoints;
            data.J3_Current_TimePoints = currentTimePoints;
            data.J4_Current_TimePoints = currentTimePoints;
            data.J5_Current_TimePoints = currentTimePoints;
            data.J6_Current_TimePoints = currentTimePoints;
            data.J1_Current = j1currentDataDecimal;
            data.J2_Current = j2currentDataDecimal;
            data.J3_Current = j3currentDataDecimal;
            data.J4_Current = j4currentDataDecimal;
            data.J5_Current = j5currentDataDecimal;
            data.J6_Current = j6currentDataDecimal;

            if (data.J1_Current != null)
            {
                decimal absTotal = 0;
                foreach (var item in data.J1_Current)
                {
                    absTotal += Math.Abs(item);
                }
                data.J1CurrentAbsAvg = Math.Round(absTotal / data.J1_Current.Count, 2);
            }
            else
            { data.J1CurrentAbsAvg = 0; }

            if (data.J2_Current != null)
            {
                decimal absTotal = 0;
                foreach (var item in data.J2_Current)
                {
                    absTotal += Math.Abs(item);
                }
                data.J2CurrentAbsAvg = Math.Round(absTotal / data.J2_Current.Count, 2);
            }
            else
            { data.J2CurrentAbsAvg = 0; }

            if (data.J3_Current != null)
            {
                decimal absTotal = 0;
                foreach (var item in data.J3_Current)
                {
                    absTotal += Math.Abs(item);
                }
                data.J3CurrentAbsAvg = Math.Round(absTotal / data.J3_Current.Count, 2);
            }
            else
            { data.J3CurrentAbsAvg = 0; }

            if (data.J4_Current != null)
            {
                decimal absTotal = 0;
                foreach (var item in data.J4_Current)
                {
                    absTotal += Math.Abs(item);
                }
                data.J4CurrentAbsAvg = Math.Round(absTotal / data.J4_Current.Count, 2);
            }
            else
            { data.J4CurrentAbsAvg = 0; }

            if (data.J5_Current != null)
            {
                decimal absTotal = 0;
                foreach (var item in data.J5_Current)
                {
                    absTotal += Math.Abs(item);
                }
                data.J5CurrentAbsAvg = Math.Round(absTotal / data.J5_Current.Count, 2);
            }
            else
            { data.J5CurrentAbsAvg = 0; }

            if (data.J6_Current != null)
            {
                decimal absTotal = 0;
                foreach (var item in data.J6_Current)
                {
                    absTotal += Math.Abs(item);
                }
                data.J6CurrentAbsAvg = Math.Round(absTotal / data.J6_Current.Count, 2);
            }
            else
            { data.J6CurrentAbsAvg = 0; }
            #endregion

            return data;

        }
        #endregion
        #region Seal measurement data
        public SealMeasurementDataForOnePartOnePassDtoOut GetNoDataOfSealMeasurement()
        {
            DateTime today = System.DateTime.Now.Date;
            SealMeasurementDataForOnePartOnePassDtoOut noData = new SealMeasurementDataForOnePartOnePassDtoOut();
            noData.Part_Serial = "";
            noData.Start_Time = today;
            noData.End_Time = today;
            noData.Insert_Time = today;
            noData.StandardTemperature = 0;
            noData.MaxTorque = 0;
            noData.MinTorque = 0;
            noData.QualityFeedBack = "";
            noData.FlowType = "";
            noData.MaterialType = "";
            noData.TotalThroughput = 0;
            noData.SealAmount = 0;
            noData.Pass_Nos = new List<int>() { 0 };
            noData.RealTimePassFlowRates = new List<decimal> { 0 };
            noData.RealTimePassFlowRateTimePoints = new List<string> { "" };
            noData.RealTimeTemperature = new List<decimal> { 0 };
            noData.RealTimeTemperatureTimePoints = new List<string> { "" };
            noData.RealTimeTorque = new List<decimal> { 0 };
            noData.RealTimeTorqueTimePoints = new List<string> { "" };

            return noData;
        }
        public SealMeasurementDataForOnePartOnePassDtoOut GetSealMeasurementDataForOnePartOnePassByPartSerialAndPassNo(string part_Serial, int pass_No)
        {
            DateTime today = System.DateTime.Now.Date;
            var lastPart_SerialOfRobot = db.Seal_Part_Unit.Where(a => a.Part_Serial == part_Serial).OrderByDescending(a => a.Start_Time).FirstOrDefault();

            if (lastPart_SerialOfRobot == null)
            {
                return GetNoDataOfSealMeasurement();
            }
            var partMeasurementData = db.Seal_Pass.Where(a => a.Part_ID == lastPart_SerialOfRobot.ID && a.Pass_No == pass_No).FirstOrDefault();
            if (partMeasurementData == null)
            {
                return GetNoDataOfSealMeasurement();
            }

            string[] realTimePassFlowRates = partMeasurementData.RealtimePassFlowRate.Split(',');
            string[] realTimeTemperature = partMeasurementData.RealtimeTemperature.Split(',');
            string[] realTimeTorque = partMeasurementData.RealtimeTorque.Split(',');

            List<decimal> realTimePassFlowRatesDecimal = new List<decimal>();
            List<decimal> realTimeTemperatureDecimal = new List<decimal>();
            List<decimal> realTimeTorqueDecimal = new List<decimal>();

            List<string> realTimePassFlowRateTimePoints = new List<string>();
            List<string> realTimeTemperatureTimePoints = new List<string>();
            List<string> realTimeTorqueTimePoints = new List<string>();


            int timePoint = 0;
            foreach (var item in realTimePassFlowRates)
            {
                realTimePassFlowRateTimePoints.Add((0.024 * timePoint).ToString());
                timePoint++;
                realTimePassFlowRatesDecimal.Add(decimal.Round(decimal.Parse(item), 2));
            }
            foreach (var item in realTimeTemperature)
            {
                //
                realTimeTemperatureDecimal.Add(decimal.Round(decimal.Parse(item), 2));
            }
            foreach (var item in realTimeTorque)
            {

                realTimeTorqueDecimal.Add(decimal.Round(decimal.Parse(item), 2));
            }
            realTimeTemperatureTimePoints = realTimePassFlowRateTimePoints;
            realTimeTorqueTimePoints = realTimePassFlowRateTimePoints;


            #region Wrap data
            SealMeasurementDataForOnePartOnePassDtoOut data = new SealMeasurementDataForOnePartOnePassDtoOut();
            data.Part_Serial = lastPart_SerialOfRobot.Part_Serial;
            data.Start_Time = lastPart_SerialOfRobot.Start_Time;
            data.End_Time = lastPart_SerialOfRobot.End_Time;
            data.Insert_Time = lastPart_SerialOfRobot.Insert_Time;
            data.StandardTemperature = lastPart_SerialOfRobot.StandardTemperture ?? 0;
            data.MaxTorque = partMeasurementData.MaxTorque ?? 0;
            data.MinTorque = partMeasurementData.MinTorque ?? 0;
            data.QualityFeedBack = partMeasurementData.QualityFeedBack;
            data.FlowType = partMeasurementData.Seal_FlowType.FlowType_Name;
            data.MaterialType = lastPart_SerialOfRobot.Seal_Material.SealMaterial;
            data.TotalThroughput = Convert.ToDecimal(lastPart_SerialOfRobot.TotalThroughput ?? 0);
            data.SealAmount = partMeasurementData.Seal_Amount ?? 0;
            data.Pass_No = pass_No;
            data.Pass_Nos = new List<int>();
            var passNos = db.Seal_Pass.Where(a => a.Part_ID == lastPart_SerialOfRobot.ID).ToList();
            foreach (var item in passNos)
            {
                data.Pass_Nos.Add(item.Pass_No);
            }
            data.RealTimePassFlowRates = realTimePassFlowRatesDecimal;
            data.RealTimePassFlowRateTimePoints = realTimePassFlowRateTimePoints;
            data.RealTimeTemperature = realTimeTemperatureDecimal;
            data.RealTimeTemperatureTimePoints = realTimeTemperatureTimePoints;
            data.RealTimeTorque = realTimeTorqueDecimal;
            data.RealTimeTorqueTimePoints = realTimeTorqueTimePoints;
            #endregion

            return data;
        }

        public SealMeasurementDataForOnePartOnePassDtoOut GetSealMeasurementDataForOnePartOnePassByRobotId(int robotId)
        {
            DateTime today = System.DateTime.Now.Date;
            var lastPart_SerialOfRobot = robotId == -1 ? db.Seal_Part_Unit.Where(a => a.Start_Time >= today).OrderByDescending(a => a.Start_Time).FirstOrDefault() : db.Seal_Part_Unit.Where(a => a.Robot_ID == robotId && a.Start_Time >= today).OrderByDescending(a => a.Start_Time).FirstOrDefault();

            if (lastPart_SerialOfRobot == null)
            {
                return GetNoDataOfSealMeasurement();
            }
            return GetSealMeasurementDataForOnePartOnePassByPartSerialAndPassNo(lastPart_SerialOfRobot.Part_Serial, 1);
        }
        #endregion
        #region Spot measurement data
        public SpotMeasurementDataForOnePointDtoOut GetNoDataOfSpotMeasurement()
        {
            DateTime today = System.DateTime.Now.Date;
            SpotMeasurementDataForOnePointDtoOut noData = new SpotMeasurementDataForOnePointDtoOut();
            noData.Part_Serial = "";
            noData.Pass_No = 0;
            noData.StartTime = today;
            noData.EndTime = today;

            noData.PlateThickness = 0;
            noData.TorqueToStressRate = 0;

            noData.StandardCurrent = 0;
            noData.StandardResistence = 0;
            noData.StandardStress = 0;

            noData.StepCount = 0;
            noData.StepCurrent = 0;
            noData.SteperNumber = 0;

            noData.Pass_Nos = new List<int> { 0 };
            noData.RealTime1stCurrent = new List<decimal> { 0 };
            noData.RealTime1stCurrentTimePoints = new List<string> { "0" };
            noData.RealTimeResistence = new List<decimal> { 0 };
            noData.RealTimeResistenceTimePoints = new List<string> { "0" };
            noData.RealTimeStress = new List<decimal> { 0 };
            noData.RealTimeStressTimePoints = new List<string> { "0" };

            return noData;
        }

        public SpotMeasurementDataForOnePointDtoOut GetSpotMeasurementDataForOnePointByPartSerialAndPointNo(string part_Serial, int pass_No)
        {
            DateTime today = System.DateTime.Now.Date;
            decimal factorK = 1;
            decimal factorB = 1;

            var lastPart_SerialOfRobot = db.Spot_Part_Unit.Where(a => a.Part_Serial == part_Serial).OrderByDescending(a => a.Start_Time).FirstOrDefault();

            if (lastPart_SerialOfRobot == null)
            {
                return GetNoDataOfSpotMeasurement();
            }
            var partMeasurementData = db.Spot_Points.Where(a => a.Part_ID == lastPart_SerialOfRobot.ID && a.Point_No == pass_No).FirstOrDefault();
            if (partMeasurementData == null)
            {
                return GetNoDataOfSpotMeasurement();
            }

            var ratio = db.Spot_TorqueToPressRatio.Where(a => a.Robot_ID == lastPart_SerialOfRobot.Robot_ID).FirstOrDefault();
            if (ratio == null)
            {
                return GetNoDataOfSpotMeasurement();
            }

            factorK = ratio.TorqueToPressRatio_k == null ? 1 : Convert.ToDecimal(ratio.TorqueToPressRatio_k);
            factorB = ratio.TorqueToPressRatio_b == null ? 1 : Convert.ToDecimal(ratio.TorqueToPressRatio_b);

            string[] realTimeTorque = partMeasurementData.RealtimeTorque.Split(',');
            string[] realTime1stCurrent = partMeasurementData.Realtime1stCurrent.Split(',');
            string[] realTimeResistence = partMeasurementData.RealtimeResistence.Split(',');

            List<decimal> realTimeStressDecimal = new List<decimal>();
            List<decimal> realTime1stCurrentDecimal = new List<decimal>();
            List<decimal> realTimeResistenceDecimal = new List<decimal>();

            List<string> realTimeStressTimePoints = new List<string>();
            List<string> realTime1stCurrentTimePoints = new List<string>();
            List<string> realTimeResistenceTimePoints = new List<string>();


            int timePointStress = 0;
            int timePointCurrent = 0;
            int timePointResistence = 0;
            foreach (var item in realTimeTorque)
            {
                realTimeStressTimePoints.Add((0.024 * timePointStress).ToString());
                timePointStress++;
                realTimeStressDecimal.Add(decimal.Round(decimal.Parse(item) * factorK + factorB, 2));
            }
            foreach (var item in realTime1stCurrent)
            {
                realTime1stCurrentTimePoints.Add((0.001 * timePointCurrent).ToString());
                timePointCurrent++;
                realTime1stCurrentDecimal.Add(decimal.Round(decimal.Parse(item), 2));
            }
            foreach (var item in realTimeResistence)
            {
                realTimeResistenceTimePoints.Add((0.001 * timePointResistence).ToString());
                timePointResistence++;
                realTimeResistenceDecimal.Add(decimal.Round(decimal.Parse(item), 2));
            }

            #region Wrap data
            SpotMeasurementDataForOnePointDtoOut data = new SpotMeasurementDataForOnePointDtoOut();
            data.Part_Serial = part_Serial;
            data.StartTime = partMeasurementData.StartTime ?? today;
            data.EndTime = partMeasurementData.EndTime ?? today;
            data.Pass_No = pass_No;
            data.Pass_Nos = new List<int>();
            var passNos = db.Spot_Points.Where(a => a.Part_ID == lastPart_SerialOfRobot.ID).ToList();
            foreach (var item in passNos)
            {
                data.Pass_Nos.Add(item.Point_No ?? 0);
            }

            data.PlateThickness = partMeasurementData.PlateThickness;
            data.TorqueToStressRate = factorK;

            data.StandardCurrent = partMeasurementData.StandardCurrent ?? 0;
            data.StandardResistence = partMeasurementData.StandardResistence ?? 0;
            data.StandardStress = partMeasurementData.StandardStress ?? 0;

            data.StepCount = partMeasurementData.StepCount ?? 0;
            data.StepCurrent = partMeasurementData.StepCurrent ?? 0;
            data.SteperNumber = partMeasurementData.SteperNumber ?? 0;


            data.RealTime1stCurrent = realTime1stCurrentDecimal;
            data.RealTime1stCurrentTimePoints = realTime1stCurrentTimePoints;
            data.RealTimeResistence = realTimeResistenceDecimal;
            data.RealTimeResistenceTimePoints = realTimeResistenceTimePoints;
            data.RealTimeStress = realTimeStressDecimal;
            data.RealTimeStressTimePoints = realTimeStressTimePoints;
            #endregion

            return data;
        }

        public SpotMeasurementDataForOnePointDtoOut GetSpotMeasurementDataForOnePointByRobotId(int robotId)
        {
            DateTime today = System.DateTime.Now.Date;
            var lastPart_SerialOfRobot = robotId == -1 ? db.Spot_Part_Unit.Where(a => a.Start_Time >= today).OrderByDescending(a => a.Start_Time).FirstOrDefault() : db.Spot_Part_Unit.Where(a => a.Robot_ID == robotId && a.Start_Time >= today).OrderByDescending(a => a.Start_Time).FirstOrDefault();

            if (lastPart_SerialOfRobot == null)
            {
                return GetNoDataOfSpotMeasurement();
            }
            return GetSpotMeasurementDataForOnePointByPartSerialAndPointNo(lastPart_SerialOfRobot.Part_Serial, 1);
        }
        #endregion

        /// <summary>
        /// 点焊
        /// </summary>
        /// <param name="part_Serial"></param>
        /// <returns></returns>
        public SpotUnitTraceDetailDtoOut GetSpotUnitTraceDetail(string part_Serial)
        {

            var partUnit = String.IsNullOrEmpty(part_Serial) == true ? db.Spot_Part_Unit.OrderByDescending(a => a.Start_Time).FirstOrDefault() : db.Spot_Part_Unit.Where(a => a.Part_Serial == part_Serial).FirstOrDefault();
            if (partUnit == null)
            { return null; }


            DateTime today = System.DateTime.Now.Date;
            decimal torqueToStressRate = 200;
            var pointsData = db.Spot_Points.Where(a => a.Part_ID == partUnit.ID).ToList();
            #region Wrap data
            SpotUnitTraceDetailDtoOut data = new SpotUnitTraceDetailDtoOut();
            data.BatchNo = partUnit.Batch;
            data.PartSerial = part_Serial;
            data.RobotNo = partUnit.Robot.YH_No;
            data.PointsData = new List<SpotUnitPassTraceRowDto>();

            foreach (var item in pointsData)
            {
                SpotUnitPassTraceRowDto row = new SpotUnitPassTraceRowDto()
                {
                    EndTime = item.EndTime,
                    InsertTime = item.InsertTime,
                    Part_Serial = part_Serial,
                    PlateThickness = item.PlateThickness,
                    Pass_No = item.Point_No,
                    StandardCurrent = item.StandardCurrent,
                    StandardResistence = item.StandardResistence,
                    StandardStress = item.StandardStress,
                    StartTime = item.StartTime,
                    StepCount = item.StepCount ?? 0,
                    StepCurrent = item.StepCurrent ?? 0,
                    SteperNumber = item.SteperNumber ?? 0,
                    StepNumber = item.StepNumber ?? 0
                };
                data.PointsData.Add(row);
            }

            #endregion

            return data;
        }

        /// <summary>
        /// 涂胶
        /// </summary>
        /// <param name="partSerialNumber"></param>
        /// <returns></returns>
        public SealUnitTraceDetailDtoOut GetSealUnitTraceDetail(string partSerialNumber)
        {
            var partUnit = String.IsNullOrEmpty(partSerialNumber) == true ? db.Seal_Part_Unit.OrderByDescending(a => a.Start_Time).FirstOrDefault() : db.Seal_Part_Unit.Where(a => a.Part_Serial == partSerialNumber).FirstOrDefault();
            if (partUnit == null)
            { return null; }


            DateTime today = System.DateTime.Now.Date;
            decimal torqueToStressRate = 200;
            var pointsData = db.Seal_Pass.Where(a => a.Part_ID == partUnit.ID).ToList();
            #region Wrap data
            SealUnitTraceDetailDtoOut data = new SealUnitTraceDetailDtoOut();
            data.BatchNo = partUnit.Batch;
            data.PartSerial = partSerialNumber;
            data.RobotNo = partUnit.Robot.YH_No;
            data.PointsData = new List<SealUnitPassTraceRowDto>();

            foreach (var item in pointsData)
            {
                SealUnitPassTraceRowDto row = new SealUnitPassTraceRowDto()
                {
                    Part_Serial = partSerialNumber,
                    Pass_No = item.Pass_No,
                    Start_Time = item.StartTime ?? DateTime.Now,
                    End_Time = item.EndTime ?? DateTime.Now,
                    Insert_Time = item.InsertTime ?? DateTime.Now,
                    StandardTemperature = partUnit.StandardTemperture ?? 0,
                    MaxTorque = item.MaxTorque ?? 0,
                    MinTorque = item.MinTorque ?? 0,
                    TotalThroughput = Convert.ToDecimal(partUnit.TotalThroughput ?? 0),
                    SealAmount = item.Seal_Amount ?? 0,
                    //QualityFeedBack = item.QualityFeedBack,
                    //FlowType = item.Seal_FlowType.FlowType_Name,
                    //MaterialType = partUnit.Seal_Material.SealMaterial,
                };
                data.PointsData.Add(row);
            }

            #endregion

            return data;
        }

        /// <summary>
        /// 打磨接口
        /// </summary>
        /// <param name="partSerialNumber"></param>
        /// <returns></returns>
        public PolishUnitTraceDetailDtoOut GetPolishUnitTraceDetail(string partSerialNumber)
        {

            var partUnit = String.IsNullOrEmpty(partSerialNumber) == true ? db.Polish_Part_Unit.OrderByDescending(a => a.Start_Time).FirstOrDefault() : db.Polish_Part_Unit.Where(a => a.Part_Serial == partSerialNumber).FirstOrDefault();
            if (partUnit == null)
            { return null; }


            DateTime today = System.DateTime.Now.Date;
            decimal torqueToStressRate = 1;
            var pointsData = db.Polish_Axis.Where(a => a.Part_ID == partUnit.ID).ToList();
            #region Wrap data
            PolishUnitTraceDetailDtoOut data = new PolishUnitTraceDetailDtoOut();
            data.BatchNo = partUnit.Batch;
            data.PartSerial = partSerialNumber;
            data.RobotNo = partUnit.Robot.YH_No;
            data.PointsData = new List<PolishUnitPassTraceRowDto>();

            foreach (var item in pointsData)
            {
                PolishUnitPassTraceRowDto row = new PolishUnitPassTraceRowDto()
                {
                    Part_Serial = partSerialNumber,
                    Start_Time = item.StartTime ?? DateTime.Now,
                    End_Time = item.EndTime ?? DateTime.Now,
                    Insert_Time = item.InsertTime ?? DateTime.Now,
                    J1CurrentLSL = partUnit.Min_Allowance_J1 == null ? 0 : Convert.ToDecimal(partUnit.Min_Allowance_J1),
                    J1CurrentUSL = partUnit.Max_Allowance_J1 == null ? 0 : Convert.ToDecimal(partUnit.Max_Allowance_J1),
                    J2CurrentLSL = partUnit.Min_Allowance_J2 == null ? 0 : Convert.ToDecimal(partUnit.Min_Allowance_J2),
                    J2CurrentUSL = partUnit.Max_Allowance_J2 == null ? 0 : Convert.ToDecimal(partUnit.Max_Allowance_J2),
                    J3CurrentLSL = partUnit.Min_Allowance_J3 == null ? 0 : Convert.ToDecimal(partUnit.Min_Allowance_J3),
                    J3CurrentUSL = partUnit.Max_Allowance_J3 == null ? 0 : Convert.ToDecimal(partUnit.Max_Allowance_J3),
                    J4CurrentLSL = partUnit.Min_Allowance_J4 == null ? 0 : Convert.ToDecimal(partUnit.Min_Allowance_J4),
                    J4CurrentUSL = partUnit.Max_Allowance_J4 == null ? 0 : Convert.ToDecimal(partUnit.Max_Allowance_J4),
                    J5CurrentLSL = partUnit.Min_Allowance_J5 == null ? 0 : Convert.ToDecimal(partUnit.Min_Allowance_J5),
                    J5CurrentUSL = partUnit.Max_Allowance_J5 == null ? 0 : Convert.ToDecimal(partUnit.Max_Allowance_J5),
                    J6CurrentLSL = partUnit.Min_Allowance_J6 == null ? 0 : Convert.ToDecimal(partUnit.Min_Allowance_J6),
                    J6CurrentUSL = partUnit.Max_Allowance_J6 == null ? 0 : Convert.ToDecimal(partUnit.Max_Allowance_J6),
                };
                data.PointsData.Add(row);
            }

            #endregion

            return data;
        }

        /// <summary>
        /// 打磨后台DTO
        /// </summary>
        /// <param name="flag"></param>
        /// <param name="partSerialNumber"></param>
        /// <returns></returns>
        public PolishUnitTraceDetailDtoOut GetPolishUnitTraceDetail(int flag, string partSerialNumber)
        {

            var partUnit = String.IsNullOrEmpty(partSerialNumber) == true ? db.Polish_Part_Unit.OrderByDescending(a => a.Start_Time).FirstOrDefault() : db.Polish_Part_Unit.Where(a => a.Part_Serial == partSerialNumber).FirstOrDefault();
            if (partUnit == null)
            { return null; }


            DateTime today = System.DateTime.Now.Date;
            decimal torqueToStressRate = 1;
            var pointsData = db.Polish_Axis.Where(a => a.Part_ID == partUnit.ID).ToList();
            #region Wrap data
            PolishUnitTraceDetailDtoOut data = new PolishUnitTraceDetailDtoOut();
            data.BatchNo = partUnit.Batch;
            data.PartSerial = partSerialNumber;
            data.RobotNo = partUnit.Robot.YH_No;
            data.PointsData = new List<PolishUnitPassTraceRowDto>();

            foreach (var item in pointsData)
            {
                PolishUnitPassTraceRowDto row = new PolishUnitPassTraceRowDto()
                {
                    Part_Serial = partSerialNumber,
                    Start_Time = item.StartTime ?? DateTime.Now,
                    End_Time = item.EndTime ?? DateTime.Now,
                    Insert_Time = item.InsertTime ?? DateTime.Now,
                    J1CurrentUSL = (partUnit.Max_Allowance_J1 == null ? 0 : Convert.ToDecimal(partUnit.Max_Allowance_J1)) - (partUnit.Min_Allowance_J1 == null ? 0 : Convert.ToDecimal(partUnit.Min_Allowance_J1)),
                    J2CurrentUSL = (partUnit.Max_Allowance_J2 == null ? 0 : Convert.ToDecimal(partUnit.Max_Allowance_J2)) - (partUnit.Min_Allowance_J2 == null ? 0 : Convert.ToDecimal(partUnit.Min_Allowance_J2)),
                    J3CurrentUSL = (partUnit.Max_Allowance_J3 == null ? 0 : Convert.ToDecimal(partUnit.Max_Allowance_J3)) - (partUnit.Min_Allowance_J3 == null ? 0 : Convert.ToDecimal(partUnit.Min_Allowance_J3)),
                    J4CurrentUSL = (partUnit.Max_Allowance_J4 == null ? 0 : Convert.ToDecimal(partUnit.Max_Allowance_J4)) - (partUnit.Min_Allowance_J4 == null ? 0 : Convert.ToDecimal(partUnit.Min_Allowance_J4)),
                    J5CurrentUSL = (partUnit.Max_Allowance_J5 == null ? 0 : Convert.ToDecimal(partUnit.Max_Allowance_J5)) - (partUnit.Min_Allowance_J5 == null ? 0 : Convert.ToDecimal(partUnit.Min_Allowance_J5)),
                    J6CurrentUSL = (partUnit.Max_Allowance_J6 == null ? 0 : Convert.ToDecimal(partUnit.Max_Allowance_J6)) - (partUnit.Min_Allowance_J6 == null ? 0 : Convert.ToDecimal(partUnit.Min_Allowance_J6)),

                    //J1CurrentLSL = partUnit.Min_Allowance_J1 == null ? 0 : Convert.ToDecimal(partUnit.Min_Allowance_J1),
                    //J1CurrentUSL = partUnit.Max_Allowance_J1 == null ? 0 : Convert.ToDecimal(partUnit.Max_Allowance_J1),
                    //J2CurrentLSL = partUnit.Min_Allowance_J2 == null ? 0 : Convert.ToDecimal(partUnit.Min_Allowance_J2),
                    //J2CurrentUSL = partUnit.Max_Allowance_J2 == null ? 0 : Convert.ToDecimal(partUnit.Max_Allowance_J2),
                    //J3CurrentLSL = partUnit.Min_Allowance_J3 == null ? 0 : Convert.ToDecimal(partUnit.Min_Allowance_J3),
                    //J3CurrentUSL = partUnit.Max_Allowance_J3 == null ? 0 : Convert.ToDecimal(partUnit.Max_Allowance_J3),
                    //J4CurrentLSL = partUnit.Min_Allowance_J4 == null ? 0 : Convert.ToDecimal(partUnit.Min_Allowance_J4),
                    //J4CurrentUSL = partUnit.Max_Allowance_J4 == null ? 0 : Convert.ToDecimal(partUnit.Max_Allowance_J4),
                    //J5CurrentLSL = partUnit.Min_Allowance_J5 == null ? 0 : Convert.ToDecimal(partUnit.Min_Allowance_J5),
                    //J5CurrentUSL = partUnit.Max_Allowance_J5 == null ? 0 : Convert.ToDecimal(partUnit.Max_Allowance_J5),
                    //J6CurrentLSL = partUnit.Min_Allowance_J6 == null ? 0 : Convert.ToDecimal(partUnit.Min_Allowance_J6),
                    //J6CurrentUSL = partUnit.Max_Allowance_J6 == null ? 0 : Convert.ToDecimal(partUnit.Max_Allowance_J6),
                };
                data.PointsData.Add(row);
            }

            #endregion

            return data;
        }

        /// <summary>
        /// 冲压接口
        /// </summary>
        /// <param name="partSerialNumber"></param>
        /// <returns></returns>
        public PressUnitTraceDetailDtoOut GetPressUnitTraceDetail(string partSerialNumber)
        {

            var partUnit = String.IsNullOrEmpty(partSerialNumber) == true ? db.Press_Part_Unit.OrderByDescending(a => a.Start_Time).FirstOrDefault() : db.Press_Part_Unit.Where(a => a.Part_Serial == partSerialNumber).FirstOrDefault();
            if (partUnit == null)
            { return null; }

            DateTime today = System.DateTime.Now.Date;
            decimal torqueToStressRate = 1;
            var pointsData = db.Press_Axis.Where(a => a.Part_ID == partUnit.ID).ToList();
            #region Wrap data
            PressUnitTraceDetailDtoOut data = new PressUnitTraceDetailDtoOut();
            data.BatchNo = partUnit.Batch;
            data.PartSerial = partSerialNumber;
            data.RobotNo = partUnit.Robot.YH_No;
            data.PointsData = new List<PressUnitPassTraceRowDto>();

            foreach (var item in pointsData)
            {
                PressUnitPassTraceRowDto row = new PressUnitPassTraceRowDto()
                {
                    Part_Serial = partSerialNumber,
                    Start_Time = item.StartTime ?? DateTime.Now,
                    End_Time = item.EndTime ?? DateTime.Now,
                    Insert_Time = item.InsertTime ?? DateTime.Now,
                    J1CurrentLSL = partUnit.Min_Allowance_J1 == null ? 0 : Convert.ToDecimal(partUnit.Min_Allowance_J1),
                    J1CurrentUSL = partUnit.Max_Allowance_J1 == null ? 0 : Convert.ToDecimal(partUnit.Max_Allowance_J1),
                    J2CurrentLSL = partUnit.Min_Allowance_J2 == null ? 0 : Convert.ToDecimal(partUnit.Min_Allowance_J2),
                    J2CurrentUSL = partUnit.Max_Allowance_J2 == null ? 0 : Convert.ToDecimal(partUnit.Max_Allowance_J2),
                    J3CurrentLSL = partUnit.Min_Allowance_J3 == null ? 0 : Convert.ToDecimal(partUnit.Min_Allowance_J3),
                    J3CurrentUSL = partUnit.Max_Allowance_J3 == null ? 0 : Convert.ToDecimal(partUnit.Max_Allowance_J3),
                    J4CurrentLSL = partUnit.Min_Allowance_J4 == null ? 0 : Convert.ToDecimal(partUnit.Min_Allowance_J4),
                    J4CurrentUSL = partUnit.Max_Allowance_J4 == null ? 0 : Convert.ToDecimal(partUnit.Max_Allowance_J4),
                    J5CurrentLSL = partUnit.Min_Allowance_J5 == null ? 0 : Convert.ToDecimal(partUnit.Min_Allowance_J5),
                    J5CurrentUSL = partUnit.Max_Allowance_J5 == null ? 0 : Convert.ToDecimal(partUnit.Max_Allowance_J5),
                    J6CurrentLSL = partUnit.Min_Allowance_J6 == null ? 0 : Convert.ToDecimal(partUnit.Min_Allowance_J6),
                    J6CurrentUSL = partUnit.Max_Allowance_J6 == null ? 0 : Convert.ToDecimal(partUnit.Max_Allowance_J6),
                };
                data.PointsData.Add(row);
            }

            #endregion

            return data;
        }

        /// <summary>
        /// 冲压后台DTO
        /// </summary>
        /// <param name="partSerialNumber"></param>
        /// <returns></returns>
        public PressUnitTraceDetailDtoOut GetPressUnitTraceDetail(int flag, string partSerialNumber)
        {

            var partUnit = String.IsNullOrEmpty(partSerialNumber) == true ? db.Press_Part_Unit.OrderByDescending(a => a.Start_Time).FirstOrDefault() : db.Press_Part_Unit.Where(a => a.Part_Serial == partSerialNumber).FirstOrDefault();
            if (partUnit == null)
            { return null; }

            DateTime today = System.DateTime.Now.Date;
            decimal torqueToStressRate = 1;
            var pointsData = db.Press_Axis.Where(a => a.Part_ID == partUnit.ID).ToList();
            var pressLineRobot = db.Press_Line_Robots.Where(a => a.Robot_ID == partUnit.Robot_ID).FirstOrDefault();
            if (pressLineRobot == null)
            {
                return null;
            }

            #region Wrap data
            PressUnitTraceDetailDtoOut data = new PressUnitTraceDetailDtoOut();
            data.BatchNo = partUnit.Batch;
            data.PartSerial = partSerialNumber;
            data.RobotNo = partUnit.Robot.YH_No;
            data.PointsData = new List<PressUnitPassTraceRowDto>();
            data.Beat = pressLineRobot.Press_Line.Beat ?? 0;
            foreach (var item in pointsData)
            {
                PressUnitPassTraceRowDto row = new PressUnitPassTraceRowDto()
                {
                    Part_Serial = partSerialNumber,
                    Start_Time = item.StartTime ?? DateTime.Now,
                    End_Time = item.EndTime ?? DateTime.Now,
                    Insert_Time = item.InsertTime ?? DateTime.Now,
                    J1CurrentUSL = (partUnit.Max_Allowance_J1 == null ? 0 : Convert.ToDecimal(partUnit.Max_Allowance_J1)) - (partUnit.Min_Allowance_J1 == null ? 0 : Convert.ToDecimal(partUnit.Min_Allowance_J1)),
                    J2CurrentUSL = (partUnit.Max_Allowance_J2 == null ? 0 : Convert.ToDecimal(partUnit.Max_Allowance_J2)) - (partUnit.Min_Allowance_J2 == null ? 0 : Convert.ToDecimal(partUnit.Min_Allowance_J2)),
                    J3CurrentUSL = (partUnit.Max_Allowance_J3 == null ? 0 : Convert.ToDecimal(partUnit.Max_Allowance_J3)) - (partUnit.Min_Allowance_J3 == null ? 0 : Convert.ToDecimal(partUnit.Min_Allowance_J3)),
                    J4CurrentUSL = (partUnit.Max_Allowance_J4 == null ? 0 : Convert.ToDecimal(partUnit.Max_Allowance_J4)) - (partUnit.Min_Allowance_J4 == null ? 0 : Convert.ToDecimal(partUnit.Min_Allowance_J4)),
                    J5CurrentUSL = (partUnit.Max_Allowance_J5 == null ? 0 : Convert.ToDecimal(partUnit.Max_Allowance_J5)) - (partUnit.Min_Allowance_J5 == null ? 0 : Convert.ToDecimal(partUnit.Min_Allowance_J5)),
                    J6CurrentUSL = (partUnit.Max_Allowance_J6 == null ? 0 : Convert.ToDecimal(partUnit.Max_Allowance_J6)) - (partUnit.Min_Allowance_J6 == null ? 0 : Convert.ToDecimal(partUnit.Min_Allowance_J6)),

                };
                data.PointsData.Add(row);
            }

            #endregion

            return data;
        }

        /// <summary>
        /// 焊接，冲压，打磨，涂胶数据交互
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public UnitListTraceDtoOutAll GetAllPassProcessDefinitionGridInfoBySerialNumber(string PartSerial)
        {
            if (!string.IsNullOrEmpty(PartSerial))
            {
                UnitListTraceDtoOutAll data = new UnitListTraceDtoOutAll();
                data.SpotTableData = GetSpotUnitTraceDetail(PartSerial);
                data.SealTableData = GetSealUnitTraceDetail(PartSerial);
                data.PolishTableData = GetPolishUnitTraceDetail(0, PartSerial);
                data.PressTableData = GetPressUnitTraceDetail(0, PartSerial);
                data.ArcWeldingTableData = GetUnitTraceDetail(PartSerial);
                //data.PageIndex = input.PageIndex + 1;
                //data.PageSize = input.PageSize;
                //data.TotalPages = input.PageSize == 0 ? 0 : db.Part_Unit.Count() / input.PageSize;

                return data;
            }
            else
            {
                return null;
            }
        }

        /// <summary>
        /// UnitListTrace后台根据工艺查询
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public UnitListTraceDtoOut GetAllUnitListTraceRecords(UnitListTraceDtoIn input)
        {
            List<Part_Unit> query = new List<Part_Unit>();
            List<Spot_Part_Unit> spotquery = new List<Spot_Part_Unit>();
            List<Seal_Part_Unit> sealquery = new List<Seal_Part_Unit>();
            List<Polish_Part_Unit> polishquery = new List<Polish_Part_Unit>();
            List<Press_Part_Unit> pressquery = new List<Press_Part_Unit>();

            UnitListTraceDtoOut data = new UnitListTraceDtoOut();

            if (input == null)
            {
                return null;
            }

            switch (input.Process)
            {
                case 0:
                    query = db.Part_Unit.Where(a =>
                   (String.IsNullOrEmpty(input.BatchNo) == true ? true : a.Batch == input.BatchNo) &&
                   (input.EndTime == null ? true : a.End_Time <= input.EndTime) &&
                   (input.StartTime == null ? true : a.End_Time >= input.StartTime) &&
                   (String.IsNullOrEmpty(input.PartName) == true ? true : a.Part_Name == input.PartName) &&
                   (String.IsNullOrEmpty(input.PartSerial) == true ? true : a.Part_Serial == input.PartSerial) &&
                      (input.StationNo == null ? true : a.Station_No == input.StationNo) &&
                   (String.IsNullOrEmpty(input.RobotNo) == true ? true : a.Robot.YH_No == input.RobotNo)
                   ).OrderBy(a => a.ID).ToList();

                    AutoMapper.Mapper.Initialize(cfg => cfg.CreateMap<Part_Unit, UnitListTraceRowDto>().ForMember(dest => dest.RobotNo, src => src.MapFrom(s => s.Robot.YH_No))
                    .ForMember(dest => dest.BatchNo, src => src.MapFrom(s => s.Batch))
                     .ForMember(dest => dest.StartTime, src => src.MapFrom(s => s.Start_Time))
                    .ForMember(dest => dest.EndTime, src => src.MapFrom(s => s.End_Time))
                    .ForMember(dest => dest.InsertTime, src => src.MapFrom(s => s.Insert_Time))
                    .ForMember(dest => dest.PartName, src => src.MapFrom(s => s.Part_Name))
                    .ForMember(dest => dest.PartSerial, src => src.MapFrom(s => s.Part_Serial))
                      .ForMember(dest => dest.QualityGrade, src => src.MapFrom(s => s.Quality_Grade))
                       .ForMember(dest => dest.Process, src => src.MapFrom(s => "ARC"))
                      .ForMember(dest => dest.StationNo, src => src.MapFrom(s => s.Station_No))
                      );

                    data.TableData = AutoMapper.Mapper.Map<List<UnitListTraceRowDto>>(query);

                    spotquery = db.Spot_Part_Unit.Where(a =>
                      (String.IsNullOrEmpty(input.BatchNo) == true ? true : a.Batch == input.BatchNo) &&
                      (input.EndTime == null ? true : a.End_Time <= input.EndTime) &&
                      (input.StartTime == null ? true : a.End_Time >= input.StartTime) &&
                      (String.IsNullOrEmpty(input.PartName) == true ? true : a.Part_Name == input.PartName) &&
                      (String.IsNullOrEmpty(input.PartSerial) == true ? true : a.Part_Serial == input.PartSerial) &&
                         (input.StationNo == null ? true : a.Station_No == input.StationNo) &&
                      (String.IsNullOrEmpty(input.RobotNo) == true ? true : a.Robot.YH_No == input.RobotNo)
                      ).OrderBy(a => a.ID).ToList();



                    foreach (var item in spotquery)
                    {
                        UnitListTraceRowDto tracemodel = new UnitListTraceRowDto();

                        tracemodel.Id = item.ID;
                        tracemodel.RobotNo = item.Robot.YH_No;
                        tracemodel.BatchNo = item.Batch;
                        tracemodel.StartTime = item.Start_Time;
                        tracemodel.EndTime = item.End_Time;
                        tracemodel.InsertTime = item.Insert_Time;
                        tracemodel.PartName = item.Part_Name;
                        tracemodel.PartSerial = item.Part_Serial;
                        tracemodel.QualityGrade = item.Quality_Grade.ToString();
                        tracemodel.Process = "SPOT";
                        tracemodel.StationNo = item.Station_No.ToString();

                        data.TableData.Add(tracemodel);
                    }

                    sealquery = db.Seal_Part_Unit.Where(a =>
                    (String.IsNullOrEmpty(input.BatchNo) == true ? true : a.Batch == input.BatchNo) &&
                    (input.EndTime == null ? true : a.End_Time <= input.EndTime) &&
                    (input.StartTime == null ? true : a.End_Time >= input.StartTime) &&
                    (String.IsNullOrEmpty(input.PartName) == true ? true : a.Part_Name == input.PartName) &&
                    (String.IsNullOrEmpty(input.PartSerial) == true ? true : a.Part_Serial == input.PartSerial) &&
                       (input.StationNo == null ? true : a.Station_No == input.StationNo) &&
                    (String.IsNullOrEmpty(input.RobotNo) == true ? true : a.Robot.YH_No == input.RobotNo)
                    ).OrderBy(a => a.ID).ToList();

                    foreach (var item in sealquery)
                    {
                        UnitListTraceRowDto tracemodel = new UnitListTraceRowDto();
                        tracemodel.Id = item.ID;
                        tracemodel.RobotNo = item.Robot.YH_No;
                        tracemodel.BatchNo = item.Batch;
                        tracemodel.StartTime = item.Start_Time;
                        tracemodel.EndTime = item.End_Time;
                        tracemodel.InsertTime = item.Insert_Time;
                        tracemodel.PartName = item.Part_Name;
                        tracemodel.PartSerial = item.Part_Serial;
                        tracemodel.QualityGrade = item.Quality_Grade.ToString();
                        tracemodel.Process = "SEAL";
                        tracemodel.StationNo = item.Station_No.ToString();

                        data.TableData.Add(tracemodel);
                    }

                    polishquery = db.Polish_Part_Unit.Where(a =>
                    (String.IsNullOrEmpty(input.BatchNo) == true ? true : a.Batch == input.BatchNo) &&
                    (input.EndTime == null ? true : a.End_Time <= input.EndTime) &&
                    (input.StartTime == null ? true : a.End_Time >= input.StartTime) &&
                    (String.IsNullOrEmpty(input.PartName) == true ? true : a.Part_Name == input.PartName) &&
                    (String.IsNullOrEmpty(input.PartSerial) == true ? true : a.Part_Serial == input.PartSerial) &&
                       (input.StationNo == null ? true : a.Station_No == input.StationNo) &&
                    (String.IsNullOrEmpty(input.RobotNo) == true ? true : a.Robot.YH_No == input.RobotNo)
                    ).OrderBy(a => a.ID).ToList();

                    foreach (var item in polishquery)
                    {
                        UnitListTraceRowDto tracemodel = new UnitListTraceRowDto();
                        tracemodel.Id = item.ID;
                        tracemodel.RobotNo = item.Robot.YH_No;
                        tracemodel.BatchNo = item.Batch;
                        tracemodel.StartTime = item.Start_Time;
                        tracemodel.EndTime = item.End_Time;
                        tracemodel.InsertTime = item.Insert_Time;
                        tracemodel.PartName = item.Part_Name;
                        tracemodel.PartSerial = item.Part_Serial;
                        tracemodel.QualityGrade = "0";
                        tracemodel.Process = "POLISH";
                        tracemodel.StationNo = item.Station_No.ToString();

                        data.TableData.Add(tracemodel);
                    }

                    pressquery = db.Press_Part_Unit.Where(a =>
                   (String.IsNullOrEmpty(input.BatchNo) == true ? true : a.Batch == input.BatchNo) &&
                   (input.EndTime == null ? true : a.End_Time <= input.EndTime) &&
                   (input.StartTime == null ? true : a.End_Time >= input.StartTime) &&
                   (String.IsNullOrEmpty(input.PartName) == true ? true : a.Part_Name == input.PartName) &&
                   (String.IsNullOrEmpty(input.PartSerial) == true ? true : a.Part_Serial == input.PartSerial) &&
                      (input.StationNo == null ? true : a.Station_No == input.StationNo) &&
                   (String.IsNullOrEmpty(input.RobotNo) == true ? true : a.Robot.YH_No == input.RobotNo)
                   ).OrderBy(a => a.ID).ToList();

                    foreach (var item in pressquery)
                    {
                        UnitListTraceRowDto tracemodel = new UnitListTraceRowDto();
                        tracemodel.Id = item.ID;
                        tracemodel.RobotNo = item.Robot.YH_No;
                        tracemodel.BatchNo = item.Batch;
                        tracemodel.StartTime = item.Start_Time;
                        tracemodel.EndTime = item.End_Time;
                        tracemodel.InsertTime = item.Insert_Time;
                        tracemodel.PartName = item.Part_Name;
                        tracemodel.PartSerial = item.Part_Serial;
                        tracemodel.QualityGrade = "0";
                        tracemodel.Process = "PRESS";
                        tracemodel.StationNo = item.Station_No.ToString();

                        data.TableData.Add(tracemodel);
                    }

                    break;
                case 1:
                    query = db.Part_Unit.Where(a =>
                   (String.IsNullOrEmpty(input.BatchNo) == true ? true : a.Batch == input.BatchNo) &&
                   (input.EndTime == null ? true : a.End_Time <= input.EndTime) &&
                   (input.StartTime == null ? true : a.End_Time >= input.StartTime) &&
                   (String.IsNullOrEmpty(input.PartName) == true ? true : a.Part_Name == input.PartName) &&
                   (String.IsNullOrEmpty(input.PartSerial) == true ? true : a.Part_Serial == input.PartSerial) &&
                      (input.StationNo == null ? true : a.Station_No == input.StationNo) &&
                   (String.IsNullOrEmpty(input.RobotNo) == true ? true : a.Robot.YH_No == input.RobotNo)
                   ).OrderBy(a => a.ID).ToList();

                    AutoMapper.Mapper.Initialize(cfg => cfg.CreateMap<Part_Unit, UnitListTraceRowDto>().ForMember(dest => dest.RobotNo, src => src.MapFrom(s => s.Robot.YH_No))
                    .ForMember(dest => dest.BatchNo, src => src.MapFrom(s => s.Batch))
                     .ForMember(dest => dest.StartTime, src => src.MapFrom(s => s.Start_Time))
                    .ForMember(dest => dest.EndTime, src => src.MapFrom(s => s.End_Time))
                    .ForMember(dest => dest.InsertTime, src => src.MapFrom(s => s.Insert_Time))
                    .ForMember(dest => dest.PartName, src => src.MapFrom(s => s.Part_Name))
                    .ForMember(dest => dest.PartSerial, src => src.MapFrom(s => s.Part_Serial))
                      .ForMember(dest => dest.QualityGrade, src => src.MapFrom(s => s.Quality_Grade))
                       .ForMember(dest => dest.Process, src => src.MapFrom(s => "ARC"))
                      .ForMember(dest => dest.StationNo, src => src.MapFrom(s => s.Station_No))
                      );

                    data.TableData = AutoMapper.Mapper.Map<List<UnitListTraceRowDto>>(query);
                    break;
                case 2:
                    spotquery = db.Spot_Part_Unit.Where(a =>
                      (String.IsNullOrEmpty(input.BatchNo) == true ? true : a.Batch == input.BatchNo) &&
                      (input.EndTime == null ? true : a.End_Time <= input.EndTime) &&
                      (input.StartTime == null ? true : a.End_Time >= input.StartTime) &&
                      (String.IsNullOrEmpty(input.PartName) == true ? true : a.Part_Name == input.PartName) &&
                      (String.IsNullOrEmpty(input.PartSerial) == true ? true : a.Part_Serial == input.PartSerial) &&
                         (input.StationNo == null ? true : a.Station_No == input.StationNo) &&
                      (String.IsNullOrEmpty(input.RobotNo) == true ? true : a.Robot.YH_No == input.RobotNo)
                      ).OrderBy(a => a.ID).ToList();

                    AutoMapper.Mapper.Initialize(cfg => cfg.CreateMap<Spot_Part_Unit, UnitListTraceRowDto>().ForMember(dest => dest.RobotNo, src => src.MapFrom(s => s.Robot.YH_No))
                      .ForMember(dest => dest.BatchNo, src => src.MapFrom(s => s.Batch))
                       .ForMember(dest => dest.StartTime, src => src.MapFrom(s => s.Start_Time))
                      .ForMember(dest => dest.EndTime, src => src.MapFrom(s => s.End_Time))
                      .ForMember(dest => dest.InsertTime, src => src.MapFrom(s => s.Insert_Time))
                      .ForMember(dest => dest.PartName, src => src.MapFrom(s => s.Part_Name))
                      .ForMember(dest => dest.PartSerial, src => src.MapFrom(s => s.Part_Serial))
                        .ForMember(dest => dest.QualityGrade, src => src.MapFrom(s => s.Quality_Grade))
                         .ForMember(dest => dest.Process, src => src.MapFrom(s => "SPOT"))
                        .ForMember(dest => dest.StationNo, src => src.MapFrom(s => s.Station_No))
                        );

                    data.TableData = AutoMapper.Mapper.Map<List<UnitListTraceRowDto>>(spotquery);
                    break;
                case 3:
                    sealquery = db.Seal_Part_Unit.Where(a =>
                     (String.IsNullOrEmpty(input.BatchNo) == true ? true : a.Batch == input.BatchNo) &&
                     (input.EndTime == null ? true : a.End_Time <= input.EndTime) &&
                     (input.StartTime == null ? true : a.End_Time >= input.StartTime) &&
                     (String.IsNullOrEmpty(input.PartName) == true ? true : a.Part_Name == input.PartName) &&
                     (String.IsNullOrEmpty(input.PartSerial) == true ? true : a.Part_Serial == input.PartSerial) &&
                        (input.StationNo == null ? true : a.Station_No == input.StationNo) &&
                     (String.IsNullOrEmpty(input.RobotNo) == true ? true : a.Robot.YH_No == input.RobotNo)
                     ).OrderBy(a => a.ID).ToList();

                    AutoMapper.Mapper.Initialize(cfg => cfg.CreateMap<Seal_Part_Unit, UnitListTraceRowDto>().ForMember(dest => dest.RobotNo, src => src.MapFrom(s => s.Robot.YH_No))
                     .ForMember(dest => dest.BatchNo, src => src.MapFrom(s => s.Batch))
                      .ForMember(dest => dest.StartTime, src => src.MapFrom(s => s.Start_Time))
                     .ForMember(dest => dest.EndTime, src => src.MapFrom(s => s.End_Time))
                     .ForMember(dest => dest.InsertTime, src => src.MapFrom(s => s.Insert_Time))
                     .ForMember(dest => dest.PartName, src => src.MapFrom(s => s.Part_Name))
                     .ForMember(dest => dest.PartSerial, src => src.MapFrom(s => s.Part_Serial))
                       .ForMember(dest => dest.QualityGrade, src => src.MapFrom(s => s.Quality_Grade))
                        .ForMember(dest => dest.Process, src => src.MapFrom(s => "SEAL"))
                       .ForMember(dest => dest.StationNo, src => src.MapFrom(s => s.Station_No))
                       );

                    data.TableData = AutoMapper.Mapper.Map<List<UnitListTraceRowDto>>(sealquery);
                    break;
                case 4:
                    polishquery = db.Polish_Part_Unit.Where(a =>
                     (String.IsNullOrEmpty(input.BatchNo) == true ? true : a.Batch == input.BatchNo) &&
                     (input.EndTime == null ? true : a.End_Time <= input.EndTime) &&
                     (input.StartTime == null ? true : a.End_Time >= input.StartTime) &&
                     (String.IsNullOrEmpty(input.PartName) == true ? true : a.Part_Name == input.PartName) &&
                     (String.IsNullOrEmpty(input.PartSerial) == true ? true : a.Part_Serial == input.PartSerial) &&
                        (input.StationNo == null ? true : a.Station_No == input.StationNo) &&
                     (String.IsNullOrEmpty(input.RobotNo) == true ? true : a.Robot.YH_No == input.RobotNo)
                     ).OrderBy(a => a.ID).ToList();

                    AutoMapper.Mapper.Initialize(cfg => cfg.CreateMap<Polish_Part_Unit, UnitListTraceRowDto>().ForMember(dest => dest.RobotNo, src => src.MapFrom(s => s.Robot.YH_No))
                    .ForMember(dest => dest.BatchNo, src => src.MapFrom(s => s.Batch))
                     .ForMember(dest => dest.StartTime, src => src.MapFrom(s => s.Start_Time))
                    .ForMember(dest => dest.EndTime, src => src.MapFrom(s => s.End_Time))
                    .ForMember(dest => dest.InsertTime, src => src.MapFrom(s => s.Insert_Time))
                    .ForMember(dest => dest.PartName, src => src.MapFrom(s => s.Part_Name))
                    .ForMember(dest => dest.PartSerial, src => src.MapFrom(s => s.Part_Serial))
                      .ForMember(dest => dest.QualityGrade, src => src.MapFrom(s => 0))
                       .ForMember(dest => dest.Process, src => src.MapFrom(s => "POLISH"))
                      .ForMember(dest => dest.StationNo, src => src.MapFrom(s => s.Station_No))
                      );

                    data.TableData = AutoMapper.Mapper.Map<List<UnitListTraceRowDto>>(polishquery);
                    break;
                case 5:
                    pressquery = db.Press_Part_Unit.Where(a =>
                     (String.IsNullOrEmpty(input.BatchNo) == true ? true : a.Batch == input.BatchNo) &&
                     (input.EndTime == null ? true : a.End_Time <= input.EndTime) &&
                     (input.StartTime == null ? true : a.End_Time >= input.StartTime) &&
                     (String.IsNullOrEmpty(input.PartName) == true ? true : a.Part_Name == input.PartName) &&
                     (String.IsNullOrEmpty(input.PartSerial) == true ? true : a.Part_Serial == input.PartSerial) &&
                        (input.StationNo == null ? true : a.Station_No == input.StationNo) &&
                     (String.IsNullOrEmpty(input.RobotNo) == true ? true : a.Robot.YH_No == input.RobotNo)
                     ).OrderBy(a => a.ID).ToList();

                    AutoMapper.Mapper.Initialize(cfg => cfg.CreateMap<Press_Part_Unit, UnitListTraceRowDto>().ForMember(dest => dest.RobotNo, src => src.MapFrom(s => s.Robot.YH_No))
                   .ForMember(dest => dest.BatchNo, src => src.MapFrom(s => s.Batch))
                    .ForMember(dest => dest.StartTime, src => src.MapFrom(s => s.Start_Time))
                   .ForMember(dest => dest.EndTime, src => src.MapFrom(s => s.End_Time))
                   .ForMember(dest => dest.InsertTime, src => src.MapFrom(s => s.Insert_Time))
                   .ForMember(dest => dest.PartName, src => src.MapFrom(s => s.Part_Name))
                   .ForMember(dest => dest.PartSerial, src => src.MapFrom(s => s.Part_Serial))
                     .ForMember(dest => dest.QualityGrade, src => src.MapFrom(s => 0))
                      .ForMember(dest => dest.Process, src => src.MapFrom(s => "PRESS"))
                     .ForMember(dest => dest.StationNo, src => src.MapFrom(s => s.Station_No))
                     );

                    data.TableData = AutoMapper.Mapper.Map<List<UnitListTraceRowDto>>(pressquery);
                    break;
            }

            data.PageIndex = input.PageIndex + 1;
            data.PageSize = input.PageSize;
            data.TotalPages = input.PageSize == 0 ? 0 : db.Part_Unit.Count() / input.PageSize;
            foreach (var item in data.TableData)
            {
                switch (item.QualityGrade)
                {
                    case "3":
                        item.QualityGrade = "NG";
                        break;
                    case "2":
                        item.QualityGrade = "OK";
                        break;
                    case "1":
                        item.QualityGrade = "Good";
                        break;
                    default:
                        item.QualityGrade = "Unknown";
                        break;
                }
            }

            return data;
        }
        #endregion
        public void Dispose()
        {
            db.Dispose();
        }
    }
}